/**
 * drwtest - 存储设备写入可靠性验证测试工具
 * Copyright (C) 2025 huwenyupeter
 * Linux移植版
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 */
// 在文件开头添加这些头文件，适用于LINUX编译
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <errno.h>
#include <signal.h>
#include <vector>
#include <string>
#include <iomanip>
#include <sstream>
#include <algorithm>
#include <cstring>
#include <malloc.h>
#include <dirent.h>
#include <linux/fs.h>
#include <sys/sysmacros.h>
#include <sys/time.h>
#include <termios.h>
#include <sys/statvfs.h> // 用于文件系统统计信息
#include <sys/ioctl.h>   // 用于设备控制
#include <linux/fs.h>    // 用于文件系统相关定义
#include <linux/hdreg.h> // 用于硬盘寄存器访问
#include <fcntl.h>       // 用于文件控制选项
#include <unistd.h>      // 用于POSIX API
#include <dirent.h>      // 用于目录操作
#include <termios.h>     // 用于终端I/O
#include <sys/select.h>  // 用于select系统调用
#include <sys/time.h>    // 用于时间函数
#include <signal.h>      // 用于信号处理
#include <limits.h>      // 用于PATH_MAX和INT_MAX
#include <stdint.h>      // 用于标准整数类型
#include <stdarg.h>      // 用于可变参数处理
#include <inttypes.h>    // 用于格式化输出
#include <fstream>
#include <iostream>
// #include <mutex>
#include <memory>
#include <chrono>
#include <stdexcept>
// std::mutex logMutex; // 用于保护日志文件操作的互斥锁
#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <cerrno>
#include <sys/file.h> // 用于文件锁操作

// 定义Windows兼容类型
typedef uint64_t ULONGLONG;
typedef uint32_t DWORD;
typedef int32_t LONG;
typedef void *LPVOID;
typedef int BOOL;
#define TRUE 1
#define FALSE 0

// 定义路径最大长度
#ifndef MAX_PATH
#define MAX_PATH PATH_MAX
#endif

// 定义驱动器类型常量
#ifndef DRIVE_UNKNOWN
#define DRIVE_UNKNOWN 0
#define DRIVE_NO_ROOT_DIR 1
#define DRIVE_REMOVABLE 2
#define DRIVE_FIXED 3
#define DRIVE_REMOTE 4
#define DRIVE_CDROM 5
#define DRIVE_RAMDISK 6
#endif

// 定义总线类型常量
#ifndef BusTypeScm
#define BusTypeScm 18
#endif

#ifndef BusTypeUfs
#define BusTypeUfs 19
#endif

// Linux特有的定义
#define INVALID_HANDLE_VALUE (-1)
typedef int HANDLE;
typedef int BOOL;
#define TRUE 1
#define FALSE 0
typedef long long LONGLONG;
typedef unsigned long long DWORDLONG;
typedef void *LPVOID;
typedef unsigned int UINT;
typedef uint32_t DWORD;
typedef int32_t LONG;
typedef uint32_t DWORD32;
typedef int32_t LONG32;
typedef uint64_t DWORD64;
typedef int64_t LONG64;

// 控制台颜色定义
#define COLOR_RESET "\033[0m"
#define COLOR_RED "\033[31m"
#define COLOR_GREEN "\033[32m"
#define COLOR_YELLOW "\033[33m"
#define COLOR_CYAN "\033[36m"
#define COLOR_WHITE "\033[37m"

// 添加超时相关的常量和变量
#define IO_TIMEOUT 30000 // 30秒超时
#define RETRY_COUNT 3    // 重试次数

// 在全局变量区域添加这些定义
unsigned int dword_413EB4, dword_413EB8, dword_413EBC, dword_413EC0;
LPVOID lpBuffer = nullptr, Block = nullptr;
int immediateVerify = 1;
int testRounds = 1;
int continueOnError = 1; // 默认出错时继续
int currentRound = 0;
char selectedDrive[256] = {0};   // Linux使用设备路径而不是盘符
double totalWrittenInRound = 0;  // 总写入数据量
double totalVerifiedInRound = 0; // 总验证数据量
FILE *logFile = nullptr;         // 当前日志
FILE *TemplogFile = nullptr;     // 临时日志
int totalErrors = 0;
int passedRounds = 0;
volatile BOOL g_bExit = FALSE;
int bufferSize = 1 * 1024 * 1024;       // 写入最小块数，默认是1M
int largeBufferSize = 16 * 1024 * 1024; // 默认缓存是16M，然后根据写入速度决定缓冲区
int targetFileSize = 2048;              // 单个文件总共2048个，相当于2048G
int deleteFilesAfterTest = 0;
DWORD bytesPerSector = 512; // 默认扇区大小
int existingFiles = 0;
double nominalCapacity = 0;
double actualCapacity = 0;

// 添加全局变量用于性能统计
double total_average_written_speed = 0;  // 平均写入速度总计
double peak_written_speed = 0;           // 峰值写入速度
double total_average_verified_speed = 0; // 平均校验速度总计
double peak_verified_speed = 0;          // 峰值校验速度
double total_test_time = 0;              // 测试总时长

// 性能优化参数
#define PROGRESS_UPDATE_INTERVAL 0.5 // 进度条更新间隔为0.5秒

// 在全局变量区域添加
#define SLOW_WRITE_THRESHOLD 1.0  // 写入延迟阈值(秒)
#define SLOW_VERIFY_THRESHOLD 1.5 // 校验延迟阈值(秒)
int slowWriteCount = 0;           // 慢写入计数
int slowVerifyCount = 0;          // 慢校验计数
int totalBlocks = 0;              // 总块数
volatile time_t lastActivityTime = 0;
char reportfilename[50] = ""; // 测试报告文件
int lockFileFd = -1; // 锁文件描述符

// 设备信息结构 (从main_s1.cpp添加)
struct DriveInfo
{
    std::string device;
    std::string mount_point;
    std::string type;
    std::string bus_type;
    std::string model;
    std::string filesystem;
    uint64_t total_size;
    uint64_t free_space;
};

// 在文件开头添加这些函数声明
void init_xorshift();
void generate_block(LPVOID buffer, size_t block_size);
int verify_block(unsigned int *data, size_t block_size);
void show_title();
const char *get_device_type_name(const char *devicePath);
std::string get_disk_bus_type(const char *devicePath);
std::vector<DriveInfo> list_drives();            // 修改为返回DriveInfo向量
void show_drive_details(const DriveInfo &drive); // 修改为使用DriveInfo
char get_user_input(const char *prompt);
void show_detailed_progress_bar(double progress, const char *color, const char *label,
                                const char *filename, double bufferMB, double currentSpeed,
                                double avgSpeed, double remainingMB, double remainingTime,
                                BOOL hasError);
void show_test_result(int totalRounds, int passedRounds, int errors, const char *deviceType);
void show_result_pattern(int status, const char *deviceType);
void delete_test_files(const std::string &devicePath);
BOOL IsDriveAvailable(const char *devicePath, ULONGLONG dwTimeoutMs);
// 在文件开头的函数声明区域添加这些声明
UINT get_device_type(const char *devicePath);
const char *get_device_type_name(const char *devicePath);
BOOL get_disk_model(const char *devicePath, char *model, int modelSize);
const char *get_basename(const char *path);

// 文件操作封装类
class FileHandler
{
public:
    enum Mode
    {
        READ,
        WRITE,
        READ_WRITE
    };

    FileHandler(const std::string &path, Mode mode);
    ~FileHandler();

    bool is_open() const;
    ssize_t read(void *buffer, size_t size);
    ssize_t write(void *buffer, size_t size);
    bool seek(uint64_t offset);
    uint64_t size() const;

private:
    int fd = -1;
};

// 文件操作类实现
FileHandler::FileHandler(const std::string &path, Mode mode)
{
    int flags = 0;
    switch (mode)
    {
    case READ:
        flags = O_RDONLY;
        break;
    case WRITE:
        flags = O_WRONLY | O_CREAT | O_TRUNC;
        break;
    case READ_WRITE:
        flags = O_RDWR | O_CREAT;
        break;
    }

    // 使用O_DIRECT标志实现直接I/O
    flags |= O_DIRECT;

    fd = open(path.c_str(), flags, 0644);
    if (fd == -1)
    {
        throw std::runtime_error("无法打开文件: " + path + " (" + std::string(strerror(errno)) + ")");
    }
}

FileHandler::~FileHandler()
{
    if (fd != -1)
    {
        close(fd);
    }
}

bool FileHandler::is_open() const
{
    return fd != -1;
}

ssize_t FileHandler::read(void *buffer, size_t size)
{
    return ::read(fd, buffer, size);
}

ssize_t FileHandler::write(void *buffer, size_t size)
{
    return ::write(fd, buffer, size);
}

bool FileHandler::seek(uint64_t offset)
{
    return lseek(fd, static_cast<off_t>(offset), SEEK_SET) != static_cast<off_t>(-1);
}

uint64_t FileHandler::size() const
{
    struct stat st;
    if (fstat(fd, &st) == -1)
    {
        return 0;
    }
    return static_cast<uint64_t>(st.st_size);
}

// Linux版本的内存对齐分配
void *aligned_alloc(size_t size, size_t alignment)
{
    void *ptr = nullptr;
    if (posix_memalign(&ptr, alignment, size) != 0)
    {
        return nullptr;
    }
    return ptr;
}

// Linux版本的内存对齐分配
void *aligned_malloc(size_t size, size_t alignment)
{
    void *ptr = NULL;
    if (posix_memalign(&ptr, alignment, size) != 0)
    {
        return NULL;
    }
    return ptr;
}

void aligned_free(void *ptr)
{
    free(ptr);
}

// Linux替代函数
void Sleep(int ms)
{
    usleep(ms * 1000);
}

time_t GetTickCount64()
{
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
}

// 格式化时间
std::string format_time(double seconds)
{
    int hours = static_cast<int>(seconds) / 3600;
    int minutes = (static_cast<int>(seconds) % 3600) / 60;
    int secs = static_cast<int>(seconds) % 60;

    char time_test[20];
    snprintf(time_test, sizeof(time_test), "%02d:%02d:%02d", hours, minutes, secs);

    return std::string(time_test);
}

void write_log(const char *format, ...)
{
    // 检查两个日志文件是否都不可用
    if (!logFile && !TemplogFile)
        return;

    time_t now = time(NULL);
    struct tm tm_info;
    localtime_r(&now, &tm_info);
    char time_str[20];
    strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", &tm_info);

    va_list args;
    va_start(args, format);

    // 当前日志 - 添加空指针检查
    if (logFile)
    {
        fprintf(logFile, "[%s] ", time_str);
        vfprintf(logFile, format, args);
        fprintf(logFile, "\n");
        fflush(logFile);
    }

    // 临时日志 - 添加双重检查
    if (TemplogFile)
    {
        // 重新初始化args，因为args在第一次vfprintf后可能不可重用
        va_end(args);
        va_start(args, format);

        fprintf(TemplogFile, "[%s] ", time_str);
        vfprintf(TemplogFile, format, args);
        fprintf(TemplogFile, "\n");
        fflush(TemplogFile);
    }

    va_end(args);
}

std::string generate_report(const char *devicePath, int totalRounds, int currentRound, int passedRounds, int errors,
                            double nominalCapacity, double actualCapacity, const char *result, const char *busType, const char *exportPath = nullptr)
{
    char reportPath[MAX_PATH];

    // 处理导出路径
    if (exportPath && strlen(exportPath) > 0)
    {
        // 确保路径格式正确
        strncpy(reportPath, exportPath, sizeof(reportPath) - 1);

        // 确保路径以斜杠结尾
        size_t len = strlen(reportPath);
        if (reportPath[len - 1] != '/')
        {
            if (len < sizeof(reportPath) - 1)
            {
                strcat(reportPath, "/");
            }
        }
    }
    else
    {
        // 获取当前工作目录
        if (getcwd(reportPath, MAX_PATH) == NULL)
        {
            strcpy(reportPath, "./");
        }
        else
        {
            size_t len = strlen(reportPath);
            if (reportPath[len - 1] != '/')
            {
                strcat(reportPath, "/");
            }
        }
    }

    // 检查目录是否存在且有写权限
    if (access(reportPath, W_OK) != 0)
    {
        printf("错误: 无法写入目录 %s: %s\n", reportPath, strerror(errno));
        // 尝试使用当前目录
        if (getcwd(reportPath, MAX_PATH) == NULL)
        {
            strcpy(reportPath, "./");
        }
        else
        {
            size_t len = strlen(reportPath);
            if (reportPath[len - 1] != '/')
            {
                strcat(reportPath, "/");
            }
        }
        printf("将使用当前目录: %s\n", reportPath);
    }

    // 生成文件名
    time_t now = time(NULL);
    struct tm tm_info;
    localtime_r(&now, &tm_info);
    char file_time_str[20];
    strftime(file_time_str, sizeof(file_time_str), "%Y%m%d%H%M%S", &tm_info);

    char filename[64] = "test_report_";
    strcat(filename, file_time_str);
    strcat(filename, ".txt");

    // 确保路径长度不会溢出
    if (strlen(reportPath) + strlen(filename) < MAX_PATH - 1)
    {
        strcat(reportPath, filename);
    }
    else
    {
        printf("错误: 报告文件路径过长\n");
        return "";
    }

    // 创建报告文件
    FILE *report = fopen(reportPath, "w");
    if (report == NULL)
    {
        printf("错误: 无法创建报告文件 %s: %s\n", reportPath, strerror(errno));
        return "";
    }
    strcpy(reportfilename, filename);

    char time_str[20];
    strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", &tm_info);

    fprintf(report, "USB/SSD写入可靠性验证测试\n");
    fprintf(report, "测试时间: %s\n", time_str);
    fprintf(report, "==================================================\n\n");

    fprintf(report, "版本: v1.3 (Linux版) Release 1.3 \n");
    fprintf(report, "测试设备: %s\n", devicePath);
    fprintf(report, "连接模式: %s\n", busType);
    fprintf(report, "总执行轮次: %d\n", totalRounds);
    fprintf(report, "已执行轮次: %d\n", currentRound);
    fprintf(report, "通过轮次: %d\n", passedRounds);
    fprintf(report, "错误数据量: %d MB\n", errors);
    fprintf(report, "标称容量: %.2f GB\n", nominalCapacity);
    fprintf(report, "实际容量: %.2f GB\n", actualCapacity);
    fprintf(report, "测试结果: %s\n\n", result);

    // 添加性能统计
    if (currentRound < 1)
        currentRound = 1; // 防止除0导致触发BUG
    fprintf(report, "性能统计:\n");
    fprintf(report, "--------------------------------------------------\n");
    int temptotalRounds = currentRound; // 检查写入和校验大小是否一至, 如果不一致则减1
    if ((totalVerifiedInRound / totalWrittenInRound) <= currentRound)
    {
        temptotalRounds = temptotalRounds - 1;
        if (temptotalRounds < 1)
            temptotalRounds = 1; // 防止除0导致触发BUG
    }
    fprintf(report, "平均写入速度: %.2f MB/s\n", total_average_written_speed / temptotalRounds);
    fprintf(report, "峰值写入速度: %.2f MB/s\n", peak_written_speed);
    fprintf(report, "总写入数据量: %.2f MB\n", totalWrittenInRound);
    fprintf(report, "平均验证速度: %.2f MB/s\n", total_average_verified_speed / currentRound);
    fprintf(report, "峰值验证速度: %.2f MB/s\n", peak_verified_speed);
    fprintf(report, "总验证数据量: %.2f MB\n", totalVerifiedInRound);
    fprintf(report, "测试总时长: %s\n", format_time(total_test_time).c_str());

    // 确保日志文件已经完全写入
    {
        // std::lock_guard<std::mutex> lock(logMutex); // 添加互斥锁
        if (TemplogFile)
        {
            fflush(TemplogFile); // 强制刷新缓冲区
            fclose(TemplogFile);
            TemplogFile = nullptr; // 明确设置为nullptr
            // 添加延迟确保文件系统完成写入
            usleep(100000); // 等待100毫秒
        }
    }

    // 添加重试机制打开日志文件
    FILE *ttemplogFile = nullptr;
    int retryCount = 0;
    const int maxRetries = 10;

    char templogPath[MAX_PATH];
    if (getcwd(templogPath, MAX_PATH) == NULL)
    {
        strcpy(templogPath, "./");
    }
    else
    {
        size_t len = strlen(templogPath);
        if (templogPath[len - 1] != '/')
        {
            strcat(templogPath, "/");
        }
    }
    strcat(templogPath, "temploglist.log");

    while (retryCount < maxRetries)
    {
        if ((ttemplogFile = fopen(templogPath, "r")) != NULL)
        {
            break;
        }
        printf("打开日志失败，可能系统在繁忙，请稍候！错误: %s\n", strerror(errno)); // 增加错误输出
        retryCount++;
        usleep(1000000);
    }

    if (ttemplogFile)
    {
        fprintf(report, "详细日志记录:\n");
        fprintf(report, "--------------------------------------------------\n");

        char line[256];
        while (fgets(line, sizeof(line), ttemplogFile))
        {
            fprintf(report, "%s", line);
        }
        fclose(ttemplogFile);
    }
    else
    {
        printf("无法打开临时日志文件 %s: %s\n", templogPath, strerror(errno)); // 增加错误输出
        fprintf(report, "无法读取日志文件\n");
    }

    fclose(report);

    return filename;
}

// 信号处理函数
void CtrlHandler(int sig)
{
    switch (sig)
    {
    case SIGINT:
    case SIGTERM:
        g_bExit = TRUE;
        // 清理锁文件
        if (lockFileFd != -1) {
            flock(lockFileFd, LOCK_UN);
            close(lockFileFd);
            remove("drwtestlock.lck");
        }
        break;
    default:
        break;
    }
}

void set_console_color(const char *color)
{
    printf("%s", color);
}

void set_cursor_position(int x, int y)
{
    printf("\033[%d;%dH", y + 1, x + 1);
}

const char *get_basename(const char *path)
{
    const char *base = strrchr(path, '/');
    return base ? base + 1 : path;
}

void init_xorshift()
{
    dword_413EB4 = 362436069;
    dword_413EB8 = 521288629;
    dword_413EBC = 88675123;
    dword_413EC0 = -593279510;
}

void generate_block(LPVOID buffer, size_t block_size)
{
    unsigned int *ptr = (unsigned int *)buffer;
    size_t blockCount = block_size / sizeof(unsigned int);
    for (size_t i = 0; i < blockCount; i++)
    {
        unsigned int temp = dword_413EB4 ^ (dword_413EB4 << 11);
        dword_413EB4 = dword_413EB8;
        dword_413EB8 = dword_413EBC;
        dword_413EBC = dword_413EC0;
        dword_413EC0 ^= temp ^ ((temp ^ (dword_413EC0 >> 11)) >> 8);
        *ptr++ = dword_413EC0;
    }
}

int verify_block(void *data, size_t block_size)
{
    // 保存当前全局状态
    unsigned int saved_dword_413EB4 = dword_413EB4;
    unsigned int saved_dword_413EB8 = dword_413EB8;
    unsigned int saved_dword_413EBC = dword_413EBC;
    unsigned int saved_dword_413EC0 = dword_413EC0;

    // 使用本地变量进行验证
    unsigned int s0 = saved_dword_413EB4;
    unsigned int s1 = saved_dword_413EB8;
    unsigned int s2 = saved_dword_413EBC;
    unsigned int s3 = saved_dword_413EC0;

    uint32_t *data_ptr = static_cast<uint32_t *>(data);
    size_t blockCount = block_size / sizeof(unsigned int);

    for (size_t i = 0; i < blockCount; i++)
    {
        unsigned int temp = s0 ^ (s0 << 11);
        s0 = s1;
        s1 = s2;
        s2 = s3;
        s3 ^= temp ^ ((temp ^ (s3 >> 11)) >> 8);

        if (*data_ptr++ != s3)
        {
            // 恢复全局状态
            dword_413EB4 = saved_dword_413EB4;
            dword_413EB8 = saved_dword_413EB8;
            dword_413EBC = saved_dword_413EBC;
            dword_413EC0 = saved_dword_413EC0;
            return 0;
        }
    }

    // 更新全局状态为验证后的状态
    dword_413EB4 = s0;
    dword_413EB8 = s1;
    dword_413EBC = s2;
    dword_413EC0 = s3;

    return 1;
}

// Linux特定的设备信息获取函数
std::string get_device_serial(const char *devicePath)
{
    char serial[256] = "未知";

    // 安全地使用strrchr
    const char *baseName = strrchr(devicePath, '/');
    if (baseName == NULL)
    {
        // 如果没有找到斜杠，使用整个设备路径
        baseName = devicePath;
    }
    else
    {
        baseName++; // 跳过斜杠
    }

    // 确保baseName不为空
    if (baseName == NULL || strlen(baseName) == 0)
    {
        return std::string(serial);
    }

    // 尝试从/sys文件系统获取序列号
    char sysPath[512];
    snprintf(sysPath, sizeof(sysPath), "/sys/block/%s/device/serial", baseName);

    FILE *f = fopen(sysPath, "r");
    if (f)
    {
        if (fgets(serial, sizeof(serial), f))
        {
            // 去除换行符
            serial[strcspn(serial, "\n")] = '\0';
        }
        fclose(f);
    }
    return std::string(serial);
}

// 获取文件系统类型
std::string get_filesystem_type(const char *mountPoint)
{
    char fsType[32] = "未知";
    FILE *mounts = fopen("/proc/mounts", "r");
    if (mounts)
    {
        char line[256];
        while (fgets(line, sizeof(line), mounts))
        {
            if (strstr(line, mountPoint))
            {
                char *tokens[6];
                int i = 0;
                char *token = strtok(line, " ");
                while (token && i < 6)
                {
                    tokens[i++] = token;
                    token = strtok(NULL, " ");
                }
                if (i >= 3)
                {
                    strncpy(fsType, tokens[2], sizeof(fsType) - 1);
                    break;
                }
            }
        }
        fclose(mounts);
    }
    return std::string(fsType);
}

// 检查当前是否具有root权限
BOOL has_root_privileges()
{
    return geteuid() == 0;
}

void show_title()
{
    set_console_color(COLOR_CYAN);
    printf("\n");
    printf("\n");
    printf("\t┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
    printf("\t┃  存储设备写入可靠性验证测试 v1.3 (Linux版) Release 1.3 ┃\n");
    printf("\t┃\t   2025-10-11   by    huwenyupeter      \t ┃\n");
    printf("\t┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n\n");
    printf("\n");
    set_console_color(COLOR_RESET);
}

const char *get_device_type_name(const char *devicePath)
{
    if (strstr(devicePath, "/dev/sd") == devicePath)
        return "SATA/USB设备";
    if (strstr(devicePath, "/dev/nvme") == devicePath)
        return "NVMe设备";
    if (strstr(devicePath, "/dev/mmcblk") == devicePath)
        return "eMMC/SD卡";
    if (strstr(devicePath, "/dev/vd") == devicePath)
        return "虚拟磁盘";
    if (strstr(devicePath, "/dev/xvd") == devicePath)
        return "Xen虚拟磁盘";
    return "块设备";
}

std::string get_disk_bus_type(const char *devicePath)
{
    const char *base_name = strrchr(devicePath, '/');
    if (!base_name)
        base_name = devicePath;
    else
        base_name++;

    char bus_type_path[256];
    snprintf(bus_type_path, sizeof(bus_type_path),
             "/sys/block/%s/device/type", base_name);

    FILE *f = fopen(bus_type_path, "r");
    if (f)
    {
        char bus_type[32];
        if (fgets(bus_type, sizeof(bus_type), f))
        {
            bus_type[strcspn(bus_type, "\n")] = '\0';
            fclose(f);

            if (strcmp(bus_type, "0") == 0)
                return "SATA";
            if (strcmp(bus_type, "1") == 0)
                return "SCSI";
            if (strcmp(bus_type, "2") == 0)
                return "NVMe";
            if (strcmp(bus_type, "3") == 0)
                return "USB";
            if (strcmp(bus_type, "4") == 0)
                return "SD/MMC";
            return bus_type;
        }
        fclose(f);
    }

    // 基于设备名称的启发式判断
    if (strstr(devicePath, "/dev/sd") == devicePath)
        return "SATA/USB";
    if (strstr(devicePath, "/dev/nvme") == devicePath)
        return "NVMe";
    if (strstr(devicePath, "/dev/mmcblk") == devicePath)
        return "SD/MMC";

    return "Unknown";
}

// 添加辅助函数获取设备类型
UINT get_device_type(const char *devicePath)
{
    // 简化实现，实际应根据设备特性判断
    if (strstr(devicePath, "/dev/sd") == devicePath)
        return DRIVE_REMOVABLE;
    if (strstr(devicePath, "/dev/nvme") == devicePath)
        return DRIVE_FIXED;
    if (strstr(devicePath, "/dev/mmcblk") == devicePath)
        return DRIVE_REMOVABLE;
    return DRIVE_UNKNOWN;
}

BOOL get_disk_model(const char *devicePath, char *model, int modelSize)
{
    // 确保缓冲区初始化
    memset(model, 0, modelSize);

    // 从设备路径提取基本名称
    const char *baseName = strrchr(devicePath, '/');
    if (baseName == NULL)
    {
        baseName = devicePath;
    }
    else
    {
        baseName++;
    }

    // 尝试从/sys文件系统获取模型信息（不需要root权限）
    char modelPath[512];
    snprintf(modelPath, sizeof(modelPath), "/sys/block/%s/device/model", baseName);
    FILE *f = fopen(modelPath, "r");
    if (f)
    {
        if (fgets(model, modelSize, f))
        {
            // 去除换行符
            model[strcspn(model, "\n")] = '\0';
            // 修剪空格
            char *end = model + strlen(model) - 1;
            while (end > model && isspace(*end))
                end--;
            *(end + 1) = '\0';
        }
        fclose(f);
    }

    // 如果无法获取模型信息，使用设备类型作为默认值
    if (strlen(model) == 0)
    {
        UINT type = get_device_type(devicePath);
        if (type == DRIVE_FIXED)
            strcpy(model, "固定硬盘");
        else if (type == DRIVE_REMOVABLE)
            strcpy(model, "可移动设备");
        else
            strcpy(model, "存储设备");
    }

    return TRUE;
}

// 驱动器列表函数
std::vector<DriveInfo> list_drives()
{
    std::vector<DriveInfo> drives;

    // 读取/proc/mounts获取挂载信息
    std::ifstream mounts("/proc/mounts");
    std::string line;

    while (std::getline(mounts, line))
    {
        std::istringstream iss(line);
        std::string device, mount_point, fs_type;

        if (iss >> device >> mount_point >> fs_type)
        {
            // 只关注块设备
            if (device.find("/dev/sd") == 0 || device.find("/dev/nvme") == 0 ||
                device.find("/dev/mmcblk") == 0)
            {

                // 获取磁盘空间信息
                struct statvfs vfs;
                if (statvfs(mount_point.c_str(), &vfs) == 0)
                {
                    DriveInfo info;
                    info.device = device;
                    info.mount_point = mount_point;
                    info.filesystem = fs_type;
                    info.total_size = static_cast<uint64_t>(vfs.f_blocks) * vfs.f_frsize;
                    info.free_space = static_cast<uint64_t>(vfs.f_bavail) * vfs.f_frsize;

                    // 简化设备类型判断
                    if (device.find("nvme") != std::string::npos)
                    {
                        info.type = "NVMe SSD";
                        info.bus_type = "NVMe";
                    }
                    else if (device.find("mmcblk") != std::string::npos)
                    {
                        info.type = "SD Card";
                        info.bus_type = "SD";
                    }
                    else
                    {
                        info.type = "Hard Disk";
                        info.bus_type = get_disk_bus_type(device.c_str());
                    }

                    // 尝试获取设备型号
                    info.model = "Unknown";
                    // 从设备路径提取基本名称
                    std::string base_name = device;
                    size_t pos = base_name.find_last_of('/');
                    if (pos != std::string::npos)
                    {
                        base_name = base_name.substr(pos + 1);
                    }

                    std::string model_path = "/sys/block/" + base_name + "/device/model";
                    std::ifstream model_file(model_path);
                    if (model_file)
                    {
                        std::getline(model_file, info.model);
                        // 清理模型字符串
                        info.model.erase(std::remove_if(info.model.begin(), info.model.end(),
                                                        [](unsigned char c)
                                                        { return std::iscntrl(c); }),
                                         info.model.end());
                    }

                    drives.push_back(info);
                }
            }
        }
    }

    return drives;
}

// 从main_s1.cpp添加的显示驱动器详细信息函数
void show_drive_details(const DriveInfo &drive)
{
    set_console_color(COLOR_CYAN);
    std::cout << "\n[" << drive.mount_point << "] 详细信息\n";
    std::cout << "===========================================\n";
    set_console_color(COLOR_RESET);

    std::cout << "设备: " << drive.device << "\n";
    std::cout << "挂载点: " << drive.mount_point << "\n";
    std::cout << "类型: " << drive.type << "\n";
    std::cout << "总线类型: " << drive.bus_type << "\n";
    std::cout << "文件系统: " << drive.filesystem << "\n";
    std::cout << "型号: " << drive.model << "\n";
    std::cout << "总容量: " << std::fixed << std::setprecision(2)
              << (drive.total_size / (1024.0 * 1024.0 * 1024.0)) << " GB\n";
    std::cout << "可用空间: " << std::fixed << std::setprecision(2)
              << (drive.free_space / (1024.0 * 1024.0 * 1024.0)) << " GB\n";

    set_console_color(COLOR_CYAN);
    std::cout << "===========================================\n\n";
    set_console_color(COLOR_RESET);
}

void clear_input_buffer()
{
    int c;
    while ((c = getchar()) != '\n' && c != EOF)
        ;
}

// 状态信息+进度条
void show_detailed_progress_bar(
    double progress,
    const char *color,
    const char *label,
    const char *filename,
    double bufferMB,
    double currentSpeed,
    double avgSpeed,
    double remainingMB,
    double remainingTime,
    BOOL hasError)
{
    const int barWidth = 30;
    int pos = (int)(barWidth * progress);

    // 使用回车符回到行首而不是清屏，避免闪烁
    printf("\r");

    // 设置颜色
    printf("%s", color);

    // 显示标签和进度条
    printf("%s [", label);
    for (int i = 0; i < barWidth; ++i)
    {
        if (i < pos)
            printf("█");
        else if (i == pos && pos % 2 == 1 && progress > 0.5)
            printf("▊");
        else if (i == pos && pos % 2 == 0 && progress > 0.5)
            printf("█");
        else
            printf(" ");
    }
    printf("] %3d%%", (int)(progress * 100));

    // 文件名显示（截断过长的文件名）
    char displayName[30];
    if (hasError)
    {
        snprintf(displayName, sizeof(displayName), "%.12s Error!", filename);
    }
    else
    {
        strncpy(displayName, filename, 20);
        displayName[19] = '\0';
    }
    printf(" | 文件: %s", displayName);

    // 缓冲区大小
    printf(" | 缓冲区: %2.0fMB", bufferMB);

    // 当前速度（根据大小自动选择单位）
    if (currentSpeed < 0.000001)
        printf(" | 当前速度: <0.1B/s");
    else if (currentSpeed < 0.0001)
        printf(" | 当前速度: %4.2fB/s", currentSpeed * 1024 * 1024);
    else if (currentSpeed < 0.1)
        printf(" | 当前速度: %4.2fKB/s", currentSpeed * 1024);
    else
        printf(" | 当前速度: %4.2fMB/s", currentSpeed);

    // 平均速度（根据大小自动选择单位）
    if (avgSpeed < 0.000001)
        printf(" | 平均速度: <0.1B/s");
    else if (avgSpeed < 0.0001)
        printf(" | 平均速度: %4.2fB/s", avgSpeed * 1024 * 1024);
    else if (avgSpeed < 0.1)
        printf(" | 平均速度: %4.2fKB/s", avgSpeed * 1024);
    else
        printf(" | 平均速度: %4.2fMB/s", avgSpeed);

    // 剩余空间
    printf(" | 剩余空间: %5.0fMB", remainingMB);

    // 剩余时间
    if (remainingTime < 0)
    {
        printf(" | 剩余时间: --:--");
    }
    else
    {
        int minutes = (int)remainingTime / 60;
        int seconds = (int)remainingTime % 60;
        printf(" | 剩余时间: %02d:%02d", minutes, seconds);
    }

    // 重置颜色并确保输出被刷新
    printf("%s", COLOR_RESET);

    // 添加空格清除可能存在的旧内容
    printf("          ");

    // 立即刷新输出
    fflush(stdout);
}

// 替换字符函数：将源字符串中的oldStr替换为newStr
char *replace_string(const char *source, const char *oldStr, const char *newStr)
{
    if (!source || !oldStr || !newStr)
        return nullptr;

    size_t sourceLen = strlen(source);
    size_t oldStrLen = strlen(oldStr);
    size_t newStrLen = strlen(newStr);

    // 计算替换次数
    size_t count = 0;
    const char *tmp = source;
    while ((tmp = strstr(tmp, oldStr)) != nullptr)
    {
        count++;
        tmp += oldStrLen;
    }

    // 计算新字符串长度（包括终止符）
    size_t newLen = sourceLen + count * (newStrLen - oldStrLen);
    char *result = (char *)malloc(newLen + 1); // +1 for null terminator
    if (!result)
        return nullptr;

    char *current = result;
    const char *start = source;
    const char *end = source;
    size_t remaining = newLen + 1; // 剩余缓冲区大小（包括终止符）

    while ((end = strstr(start, oldStr)) != nullptr)
    {
        // 计算非匹配部分的长度
        size_t chunkLen = end - start;

        // 安全复制非匹配部分
        if (chunkLen > 0)
        {
            size_t toCopy = chunkLen < remaining ? chunkLen : remaining - 1;
            if (toCopy > 0)
            {
                strncpy(current, start, toCopy);
                current += toCopy;
                remaining -= toCopy;
            }
        }

        // 安全复制新字符串
        size_t toCopy = newStrLen < remaining ? newStrLen : remaining - 1;
        if (toCopy > 0)
        {
            strncpy(current, newStr, toCopy);
            current += toCopy;
            remaining -= toCopy;
        }

        // 移动指针
        start = end + oldStrLen;
    }

    // 安全复制剩余部分
    size_t chunkLen = strlen(start);
    size_t toCopy = chunkLen < remaining ? chunkLen : remaining - 1;
    if (toCopy > 0)
    {
        snprintf(current, toCopy, "%s", start);
        // strncpy(current, start, toCopy);
        current += toCopy;
        remaining -= toCopy;
    }

    // 添加终止符
    if (remaining > 0)
    {
        *current = '\0';
    }
    else
    {
        // 确保终止符存在
        result[newLen] = '\0';
    }

    return result;
}

// 检查设备是否仍挂载在指定挂载点
BOOL is_mount_point_valid(const char *mountPoint)
{
    FILE *mounts = fopen("/proc/mounts", "r");
    if (mounts)
    {
        char line[256];
        while (fgets(line, sizeof(line), mounts))
        {
            char *token = strtok(line, " ");
            token = strtok(NULL, " "); // 第二个token是挂载点
            if (token && strcmp(token, mountPoint) == 0)
            {
                fclose(mounts);
                return TRUE;
            }
        }
        fclose(mounts);
    }
    return FALSE;
}

void show_result_pattern(int status, const char *deviceType)
{
    // 根据设备类型选择图标
    const char *iconTemplate = nullptr;
    if (strstr(deviceType, "USB") != nullptr || strstr(deviceType, "移动") != nullptr)
    {
        // U盘图标
        iconTemplate =
            "\t *************** \n"
            "\t *  ╔══════╗    *\n"
            "\t * ╔╝  USB ╚╗   *\n"
            "\t *╔╝        ╚╗  *\n"
            "\t *║    +    ║  *\n"
            "\t *╚╗        ╔╝  *\n"
            "\t * ╚╗      ╔╝   *\n"
            "\t *  ╚══════╝    *\n"
            "\t *************** \n";
    }
    else
    {
        // 硬盘图标
        iconTemplate =
            "\t***************\n"
            "\t* ╔════════╗   *\n"
            "\t*╔╝        ╚╗  *\n"
            "\t*║          ║  *\n"
            "\t*║    +    ║  *\n"
            "\t*║          ║  *\n"
            "\t*╚╗        ╔╝  *\n"
            "\t* ╚════════╝   *\n"
            "\t***************\n";
    }

    char *icon;

    // 根据状态选择颜色和符号
    const char *color;
    switch (status)
    {
    case 0: // 失败
        color = COLOR_RED;
        icon = replace_string(iconTemplate, "*", "×");
        icon = replace_string(icon, "+", "NO");
        break;
    case 1: // 成功
        color = COLOR_GREEN;
        icon = replace_string(iconTemplate, "*", "√");
        icon = replace_string(icon, "+", "OK");
        break;
    case 2: // 警告
        color = COLOR_YELLOW;
        icon = replace_string(iconTemplate, "*", "！");
        icon = replace_string(icon, "+", "！");
        break;
    default:
        return;
    }

    if (!icon)
    {
        // 添加错误处理
        set_console_color(COLOR_RED);
        printf("图标生成失败\n");
        set_console_color(COLOR_RESET);
        return;
    }

    // 在图标下方打印符号
    set_console_color(color);
    printf("\n");
    printf("%s", icon);
    set_console_color(COLOR_RESET);

    free(icon); // 释放内存
}

// 显示测试结果
void show_test_result(int totalRounds, int passedRounds, int errors, const char *deviceType)
{
    set_console_color(COLOR_WHITE);
    printf("\n执行 %d 轮测试", totalRounds);

    // 计算进度
    double progress = (double)passedRounds / totalRounds;
    const char *color = COLOR_GREEN;

    if (passedRounds == totalRounds && errors == 0)
    {
        color = COLOR_GREEN;
        set_console_color(color);
        printf(" - 全部通过验证无错误!\n");
        show_result_pattern(1, deviceType);
    }
    else if (errors > 0)
    {
        color = COLOR_RED;
        set_console_color(color);
        printf(" - 检测到 %d MB 数据错误!\n", errors);
        show_result_pattern(0, deviceType);
    }
    else
    {
        color = COLOR_YELLOW;
        set_console_color(color);
        printf(" - %d/%d 轮通过验证!\n", passedRounds, totalRounds);
        show_result_pattern(2, deviceType);
    }

    // 显示总结进度条
    set_console_color(color);
    printf("\n[");
    int pos = static_cast<int>(30 * progress + 0.5); // 添加四舍五入
    for (int i = 0; i < 30; ++i)
    {
        if (i < pos)
            printf("█");
        else if (i == pos && pos % 2 == 1 && progress > 0.5)
            printf("▊");
        else if (i == pos && pos % 2 == 0 && progress > 0.5)
            printf("█");
        else
            printf(" ");
    }
    printf(" ] %3d%%", (int)(progress * 100));
    set_console_color(COLOR_RESET);
    printf("\n");
}

// 检查是否存在测试文件
int check_existing_files(const char *devicePath)
{
    char mountPoint[256] = {0};
    char fileName[MAX_PATH];
    int fileCount = 0;

    // 尝试查找设备的挂载点
    FILE *mounts = fopen("/proc/mounts", "r");
    if (mounts)
    {
        char line[256];
        while (fgets(line, sizeof(line), mounts))
        {
            if (strstr(line, devicePath))
            {
                char *token = strtok(line, " ");
                token = strtok(NULL, " "); // 第二个token是挂载点
                if (token)
                {
                    strncpy(mountPoint, token, sizeof(mountPoint) - 1);
                    break;
                }
            }
        }
        fclose(mounts);
    }

    // 如果没有找到挂载点，直接返回0
    if (mountPoint[0] == '\0')
    {
        return 0;
    }

    for (int i = 1; i <= 100; i++)
    {
        snprintf(fileName, sizeof(fileName), "%s/DRW%05d.BIN", mountPoint, i);
        FILE *file;
        if ((file = fopen(fileName, "rb")) != NULL)
        {
            fclose(file);
            fileCount++;
        }
        else
        {
            break;
        }
    }
    return fileCount > 0;
}

// 获取当前高精度时间
double get_current_time()
{
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    return (double)ts.tv_sec + (double)ts.tv_nsec / 1e9;
}

// 删除测试文件
void delete_test_files(const std::string &mount_point)
{
    set_console_color(COLOR_YELLOW);
    std::cout << "\n删除测试文件..." << std::endl;
    set_console_color(COLOR_RESET);

    write_log("删除测试文件: %s", mount_point.c_str());

    int deleted_count = 0;
    for (int i = 1;; i++)
    {
        std::ostringstream oss;
        oss << mount_point << "/DRW" << std::setfill('0') << std::setw(5) << i << ".BIN";
        std::string filename = oss.str();

        if (remove(filename.c_str()) != 0)
        {
            if (errno == ENOENT)
                break; // 文件不存在，停止删除
            set_console_color(COLOR_RED);
            std::cerr << "删除失败: " << filename << " (" << strerror(errno) << ")" << std::endl;
            set_console_color(COLOR_RESET);
        }
        else
        {
            deleted_count++;
        }
    }

    if (deleted_count > 0)
    {
        set_console_color(COLOR_GREEN);
        std::cout << "已删除 " << deleted_count << " 个测试文件" << std::endl;
        set_console_color(COLOR_RESET);
        write_log("已删除 %d 个测试文件", deleted_count);
    }
    else
    {
        set_console_color(COLOR_YELLOW);
        std::cout << "未找到测试文件" << std::endl;
        set_console_color(COLOR_RESET);
    }
}

// 调整缓冲区大小
void adjust_buffer_size()
{
    if (targetFileSize == 2048)
    {
        bufferSize = largeBufferSize;
        if (logFile)
        {
            write_log("使用大缓冲区: 16MB");
        }
    }
    else
    {
        bufferSize = 1 * 1024 * 1024;
    }
}

// 设备状态检测
BOOL IsDriveAvailable(const char *devicePath, ULONGLONG dwTimeoutMs)
{
    // 检查设备是否存在
    ULONGLONG startTime = GetTickCount64();
    while (GetTickCount64() - startTime < dwTimeoutMs)
    {
        usleep(100000); // 短暂等待100ms
        struct stat st;
        if (stat(devicePath, &st) == 0 && S_ISBLK(st.st_mode))
        {
            return TRUE; // 设备存在
        }
    }

    return FALSE; // 设备超时未恢复
}

// 同步写入带超时
BOOL SyncWriteWithTimeout(int fd, LPVOID lpBuffer, DWORD nNumberOfBytesToWrite,
                          DWORD *lpNumberOfBytesWritten, ULONGLONG dwTimeoutMs)
{
    ULONGLONG startTime = GetTickCount64();
    ssize_t bytesWritten = 0;
    BOOL result = FALSE;

    bytesWritten = write(fd, lpBuffer, nNumberOfBytesToWrite);

    if (bytesWritten == nNumberOfBytesToWrite)
    {
        if (lpNumberOfBytesWritten)
            *lpNumberOfBytesWritten = bytesWritten;
        return TRUE;
    }

    // 检查是否超时
    if (GetTickCount64() - startTime > dwTimeoutMs)
    {
        errno = ETIMEDOUT;
        return FALSE;
    }

    return result;
}

// 同步读取带超时
BOOL SyncReadWithTimeout(int fd, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
                         DWORD *lpNumberOfBytesRead, ULONGLONG dwTimeoutMs)
{
    ULONGLONG startTime = GetTickCount64();
    ssize_t bytesRead = 0;
    BOOL result = FALSE;

    bytesRead = read(fd, lpBuffer, nNumberOfBytesToRead);

    if (bytesRead == nNumberOfBytesToRead)
    {
        if (lpNumberOfBytesRead)
            *lpNumberOfBytesRead = bytesRead;
        return TRUE;
    }

    // 检查是否超时
    if (GetTickCount64() - startTime > dwTimeoutMs)
    {
        errno = ETIMEDOUT;
        return FALSE;
    }

    return result;
}

// 获取用户输入
char get_user_input(const char *prompt)
{
    printf("%s", prompt);
    char input[10];
    if (fgets(input, sizeof(input), stdin) == NULL)
    {
        return '\0';
    }
    return toupper(input[0]);
}

// 添加文件占用检测函数
bool is_file_locked(const char *filename)
{
    int fd = open(filename, O_RDWR);
    if (fd == -1)
    {
        return (errno == EACCES || errno == EAGAIN);
    }
    close(fd);
    return false;
}

std::string get_full_path(const char *filename)
{
    char path[MAX_PATH];
    if (getcwd(path, sizeof(path)) == NULL)
    {
        return std::string("./") + filename;
    }
    return std::string(path) + "/" + filename;
}

// 辅助函数: 检查日志行格式是否有效（以 [YYYY-MM-DD HH:MM:SS] 开头）
int is_valid_log_line(const char *line)
{
    if (strlen(line) < 21)
        return 0;
    if (line[0] != '[')
        return 0;
    // 检查年份部分（索引1-4）
    for (int i = 1; i <= 4; i++)
    {
        if (line[i] < '0' || line[i] > '9')
            return 0;
    }
    if (line[5] != '-')
        return 0;
    // 检查月份部分（索引6-7）
    for (int i = 6; i <= 7; i++)
    {
        if (line[i] < '0' || line[i] > '9')
            return 0;
    }
    if (line[8] != '-')
        return 0;
    // 检查日期部分（索引9-10）
    for (int i = 9; i <= 10; i++)
    {
        if (line[i] < '0' || line[i] > '9')
            return 0;
    }
    if (line[11] != ' ')
        return 0; // 索引11应为空格
    // 检查小时部分（索引12-13）
    for (int i = 12; i <= 13; i++)
    {
        if (line[i] < '0' || line[i] > '9')
            return 0;
    }
    if (line[14] != ':')
        return 0; // 索引14应为冒号
    // 检查分钟部分（索引15-16）
    for (int i = 15; i <= 16; i++)
    {
        if (line[i] < '0' || line[i] > '9')
            return 0;
    }
    if (line[17] != ':')
        return 0; // 索引17应为冒号
    // 检查秒钟部分（索引18-19）
    for (int i = 18; i <= 19; i++)
    {
        if (line[i] < '0' || line[i] > '9')
            return 0;
    }
    if (line[20] != ']')
        return 0; // 索引20应为右括号
    return 1;
}

// 辅助函数: 将时间字符串转换为 time_t
time_t parse_timestamp(const char *timestamp)
{
    struct tm tm;
    memset(&tm, 0, sizeof(tm)); // 清零整个结构体

    int year, month, day, hour, minute, second;

    if (sscanf(timestamp, "[%d-%d-%d %d:%d:%d]",
               &year, &month, &day, &hour, &minute, &second) == 6)
    {
        tm.tm_year = year - 1900;
        tm.tm_mon = month - 1;
        tm.tm_mday = day;
        tm.tm_hour = hour;
        tm.tm_min = minute;
        tm.tm_sec = second;
        tm.tm_isdst = -1; // 让系统自动判断夏令时

        return mktime(&tm);
    }
    return 0;
}

// 主函数: 导出异常测试报告
void export_exception_test_report(const char *logFilePath)
{
    FILE *logFile;
    if ((logFile = fopen(logFilePath, "r")) == NULL)
    {
        printf("无法打开日志文件 %s: %s\n", logFilePath, strerror(errno));
        return;
    }

    // 记录开始时间
    time_t startTime = time(nullptr);
    int lineCount = 0;
    int passedRounds = 0;
    int testRounds = 0;   // 总测试轮次
    int currentRound = 0; // 已执行轮次
    int errorRounds = 0;  // 失败次数
    int errorMB = 0;      // 错误数据量（MB）
    char line[256];
    char driveFromLog[256] = {0}; // 从日志中提取的设备路径
    int writeCount = 0;
    double nominalCapacity = 0; // 标称容量
    double actualCapacity = 0;  // 实际容量
    double totalWriteData = 0.0;
    double totalVerifyData = 0.0;
    double maxWriteSpeed = 0.0;
    double maxVerifySpeed = 0.0;
    double totalWriteCurrentSpeed = 0.0;
    double totalVerifyCurrentSpeed = 0.0;
    int verifyCount = 0;
    time_t firstTimestamp = 0;
    time_t lastTimestamp = 0;

    while (fgets(line, sizeof(line), logFile) != nullptr)
    {
        lineCount++;

        // 统一化逗号格式: 将中文逗号替换为英文逗号
        std::string lineStr(line);
        size_t pos = 0;
        while ((pos = lineStr.find("，", pos)) != std::string::npos)
        {
            lineStr.replace(pos, 3, ","); // 中文逗号占3字节
            pos += 1;
        }
        strcpy(line, lineStr.c_str());

        // 检查通过轮数
        if (strstr(line, "轮验证通过") != nullptr)
        {
            passedRounds++;
        }

        // 检查测试设备信息
        if (strstr(line, "测试设备:") != nullptr)
        {
            char *deviceStart = strstr(line, "测试设备:");
            if (deviceStart != nullptr)
            {
                deviceStart += strlen("测试设备:");
                // 跳过空格
                while (*deviceStart == ' ')
                    deviceStart++;
                strncpy(driveFromLog, deviceStart, sizeof(driveFromLog) - 1);
                // 清理字符串
                driveFromLog[strcspn(driveFromLog, "\n")] = '\0';
            }
        }

        // 检查开始测试行, 提取总测试轮次
        if (strstr(line, "开始测试:") != nullptr)
        {
            char *startPos = strstr(line, "开始测试:");
            if (startPos != nullptr)
            {
                startPos += strlen("开始测试:");
                // 跳过空格
                while (*startPos == ' ')
                    startPos++;
                // 解析格式: "当前轮次/总轮次"
                int totalRounds = 0;
                if (sscanf(startPos, "%d/%d", &currentRound, &totalRounds) == 2)
                {
                    testRounds = totalRounds;
                }
            }
        }

        // 检查标称容量行, 提取标称容量
        if (strstr(line, "标称容量:") != nullptr)
        {
            char *startPos = strstr(line, "标称容量:");
            if (startPos != nullptr)
            {
                startPos += strlen("标称容量:");
                while (*startPos == ' ')
                    startPos++;
                double tempCapacity = 0.0;
                if (sscanf(startPos, "%lf", &tempCapacity) == 1)
                {
                    nominalCapacity = tempCapacity;
                }
            }
        }

        // 检查实际容量行, 提取实际容量
        if (strstr(line, "实际容量:") != nullptr)
        {
            char *startPos = strstr(line, "实际容量:");
            if (startPos != nullptr)
            {
                startPos += strlen("实际容量:");
                while (*startPos == ' ')
                    startPos++;
                double tempCapacity = 0.0;
                if (sscanf(startPos, "%lf", &tempCapacity) == 1)
                {
                    actualCapacity = tempCapacity;
                }
            }
        }

        // 解析时间戳（如果存在）
        if (is_valid_log_line(line))
        {
            char timestamp[21];
            strncpy(timestamp, line, 20);
            timestamp[20] = '\0';

            time_t currentTime = parse_timestamp(timestamp);
            if (currentTime > 0)
            {
                if (firstTimestamp == 0)
                {
                    firstTimestamp = currentTime;
                }
                lastTimestamp = currentTime;
            }
        }

        // 成功写入相关代码，数据解析逻辑
        if (strstr(line, "成功写入") != nullptr)
        {
            // 查找逗号位置（文件名后的第一个逗号）
            char *commaPos = strchr(line, ',');
            if (commaPos != nullptr)
            {
                // 跳过逗号和可能存在的空格
                char *numStart = commaPos + 1;
                while (*numStart == ' ')
                    numStart++;

                // 查找"MB"字符串
                char *mbPos = strstr(numStart, " MB");
                if (mbPos == nullptr)
                {
                    mbPos = strstr(numStart, "MB");
                }

                if (mbPos != nullptr)
                {
                    // 提取数字部分
                    char numBuffer[32] = {0};
                    size_t numLen = mbPos - numStart;
                    if (numLen > 0 && numLen < sizeof(numBuffer))
                    {
                        strncpy(numBuffer, numStart, numLen);
                        double dataSize = atof(numBuffer);
                        if (dataSize >= 0)
                        {
                            totalWriteData += dataSize;

                            // 解析速度信息
                            char *speedPos = strstr(line, "当前速度");
                            if (speedPos != nullptr)
                            {
                                double currentSpeed = 0.0;
                                if (sscanf(speedPos, "当前速度 %lf", &currentSpeed) == 1)
                                {
                                    totalWriteCurrentSpeed += currentSpeed;
                                    writeCount++;
                                    if (currentSpeed > maxWriteSpeed)
                                    {
                                        maxWriteSpeed = currentSpeed;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        // 解析成功验证行
        if (strstr(line, "成功验证") != nullptr)
        {
            // 查找逗号位置（文件名后的第一个逗号）
            char *commaPos = strchr(line, ',');
            if (commaPos != nullptr)
            {
                // 跳过逗号和可能存在的空格
                char *numStart = commaPos + 1;
                while (*numStart == ' ')
                    numStart++;

                // 查找"MB"字符串
                char *mbPos = strstr(numStart, " MB");
                if (mbPos == nullptr)
                {
                    mbPos = strstr(numStart, "MB");
                }

                if (mbPos != nullptr)
                {
                    // 提取数字部分
                    char numBuffer[32] = {0};
                    size_t numLen = mbPos - numStart;
                    if (numLen > 0 && numLen < sizeof(numBuffer))
                    {
                        strncpy(numBuffer, numStart, numLen);
                        double dataSize = atof(numBuffer);
                        if (dataSize >= 0)
                        {
                            totalVerifyData += dataSize;

                            // 解析速度信息
                            char *speedPos = strstr(line, "当前速度");
                            if (speedPos != nullptr)
                            {
                                double currentSpeed = 0.0;
                                if (sscanf(speedPos, "当前速度 %lf", &currentSpeed) == 1)
                                {
                                    totalVerifyCurrentSpeed += currentSpeed;
                                    verifyCount++;
                                    if (currentSpeed > maxVerifySpeed)
                                    {
                                        maxVerifySpeed = currentSpeed;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        // 检查验证失败行, 提取错误数据量
        if (strstr(line, "验证失败") != nullptr)
        {
            // 查找逗号位置（文件名后的第一个逗号）
            char *commaPos = strchr(line, ',');
            if (commaPos != nullptr)
            {
                // 跳过逗号和可能存在的空格
                char *numStart = commaPos + 1;
                while (*numStart == ' ')
                    numStart++;

                // 查找"MB"字符串
                char *mbPos = strstr(numStart, " MB");
                if (mbPos == nullptr)
                {
                    mbPos = strstr(numStart, "MB");
                }

                if (mbPos != nullptr)
                {
                    // 提取数字部分
                    char numBuffer[32] = {0};
                    size_t numLen = mbPos - numStart;
                    if (numLen > 0 && numLen < sizeof(numBuffer))
                    {
                        strncpy(numBuffer, numStart, numLen);
                        double dataSize = atof(numBuffer);
                        if (dataSize > 0)
                        {
                            // 使用四舍五入转换为整数MB
                            errorMB += static_cast<int>(dataSize + 0.5);
                        }
                    }
                }
            }
        }
    }

    fclose(logFile);

    // 计算平均速度
    double avgWriteSpeed = (writeCount > 0) ? totalWriteCurrentSpeed / writeCount : 0.0;
    double avgVerifySpeed = (verifyCount > 0) ? totalVerifyCurrentSpeed / verifyCount : 0.0;

    // 计算测试总时长
    double totalTimeSeconds = 0.0;
    if (firstTimestamp != 0 && lastTimestamp != 0)
    {
        totalTimeSeconds = difftime(lastTimestamp, firstTimestamp);
    }

    // 获取总线类型
    std::string busType = "未知";
    if (strlen(driveFromLog) > 0)
    {
        busType = get_disk_bus_type(driveFromLog);
    }

    // 生成结果消息
    char result[256];
    if (errorMB > 0)
    {
        snprintf(result, sizeof(result), "测试被中断, 检测到 %d MB 数据错误", errorMB);
    }
    else
    {
        snprintf(result, sizeof(result), "测试被中断, 已完成 %d 轮验证无错误", passedRounds);
    }

    // 在生成报告时使用提取的数据
    if (testRounds == 0)
    {
        testRounds = 1;
    }
    if (currentRound == 0)
    {
        currentRound = 1;
    }

    // 导出测试报告必须记录至全局变量
    totalWrittenInRound = totalWriteData;
    totalVerifiedInRound = totalVerifyData;
    total_average_written_speed = avgWriteSpeed * (testRounds > 0 ? testRounds : 1);
    total_average_verified_speed = avgVerifySpeed * (testRounds > 0 ? testRounds : 1);
    peak_written_speed = maxWriteSpeed;
    peak_verified_speed = maxVerifySpeed;
    total_test_time = totalTimeSeconds;

    // 生成报告
    if (strlen(driveFromLog) > 0)
    {
        generate_report(driveFromLog, testRounds, currentRound, passedRounds, errorMB, nominalCapacity, actualCapacity, result, busType.c_str(), nullptr);
    }

    // 输出统计信息
    printf("===== 异常测试报告 =====\n");
    if (strlen(driveFromLog) > 0)
    {
        printf("测试设备: %s\n", driveFromLog);
    }
    else
    {
        printf("测试设备: 未找到\n");
    }

    // 输出统计信息
    printf("读取文件大小总共 %d 行, 用时 %.2f 秒\n", lineCount, difftime(time(nullptr), startTime));
    printf("总写入数据量: %.2f MB\n", totalWriteData);
    printf("平均写入速度: %.2f MB/s\n", avgWriteSpeed);
    printf("峰值写入速度: %.2f MB/s\n", maxWriteSpeed);
    printf("总验证数据量: %.2f MB\n", totalVerifyData);
    printf("平均验证速度: %.2f MB/s\n", avgVerifySpeed);
    printf("峰值验证速度: %.2f MB/s\n", maxVerifySpeed);
    printf("写入和校验失败总计: %d 次\n", errorRounds);

    // 使用四舍五入转换时间
    int totalMinutes = static_cast<int>((totalTimeSeconds / 60) + 0.5);
    printf("测试总时长: %.2f 秒 (约 %d 分钟)\n", totalTimeSeconds, totalMinutes);

    // 删除临时日志文件
    if (remove(logFilePath) == 0)
    {
        printf("已删除临时日志文件\n");
    }
    else
    {
        printf("删除临时日志文件失败: %s\n", strerror(errno));
    }
}

int main(int argc, char *argv[])
{
    // 设置信号处理程序
    signal(SIGINT, CtrlHandler);
    signal(SIGTERM, CtrlHandler);

    // 检查日志文件占用情况
    const char *logFiles[] = {"loglist.log", "temploglist.log"};
    bool hasLockedFile = false;

    for (int i = 0; i < 2; i++)
    {
        std::string fullPath = get_full_path(logFiles[i]);
        if (is_file_locked(fullPath.c_str()))
        {
            set_console_color(COLOR_RED);
            printf("错误: 文件 %s 被其他程序占用！\n", logFiles[i]);
            printf("可能的原因: \n");
            printf("1. 另一个drwtest程序正在运行\n");
            printf("2. 文本编辑器或其他程序正在打开该文件\n");
            printf("3. 杀毒软件正在扫描该文件\n\n");
            printf("解决方法: \n");
            printf("1. 关闭正在使用该文件的程序\n");
            printf("2. 如果找不到占用程序, 可以尝试重启电脑\n");
            printf("3. 临时重命名或移动该文件\n");
            set_console_color(COLOR_RESET);
            hasLockedFile = true;
        }
    }
	
	// 检查是否已有实例运行
    lockFileFd = open("drwtestlock.lck", O_CREAT | O_RDWR, 0644);
    if (lockFileFd == -1) {
        set_console_color(COLOR_RED);
        printf("错误: 无法创建锁文件\n");
        set_console_color(COLOR_RESET);
        hasLockedFile = true;
    }

    // 尝试获取独占锁
    if (flock(lockFileFd, LOCK_EX | LOCK_NB) == -1) {
        set_console_color(COLOR_RED);
        printf("错误: 程序已在运行中，请勿重复运行\n");
        set_console_color(COLOR_RESET);
        close(lockFileFd);
        hasLockedFile = true;
    }

    if (hasLockedFile)
    {
        printf("\n按任意键退出...");
        getchar();
        return 1;
    }

    // 在程序开始处，检查现有日志文件
    struct stat fileStat;
    if (stat(get_full_path("temploglist.log").c_str(), &fileStat) == 0)
    {
        // 检查文件大小 (2MB = 2 * 1024 * 1024)
        if (fileStat.st_size > 2 * 1024 * 1024)
        {
            printf("文件大小超过2M, 要花一些时间, 是否要生成测试报告？(Y/N): ");
            int choice = getchar();
            if (choice == 'N' || choice == 'n')
            {
                // 重命名文件
                char newName[256];
                time_t now = time(nullptr);
                struct tm timeInfo;
                localtime_r(&now, &timeInfo);
                strftime(newName, sizeof(newName), "temploglist_%Y%m%d%H%M%S.log", &timeInfo);
                if (rename(get_full_path("temploglist.log").c_str(), get_full_path(newName).c_str()) < 0)
                {
                    set_console_color(COLOR_RED);
                    printf("\n重命名文件失败！可能文件已占用, 请检查！\n");
                    printf("如果要继续运行程序, 请重命名temploglist.log文件或者删除temploglist.log文件！\n");
                    set_console_color(COLOR_RESET);
                    getchar();
                    return 0;
                }
                printf("\n已重命名文件为: %s\n", newName);
            }
            else
            {
                export_exception_test_report(get_full_path("temploglist.log").c_str());
            }
        }
        else
        {
            export_exception_test_report(get_full_path("temploglist.log").c_str());
        }
    }

    // 定义延迟阈值和警告计数器
    int slowWriteCount = 0;  // 慢写入计数
    int slowVerifyCount = 0; // 慢校验计数
    int totalBlocks = 0;     // 总块数
    int fd = -1;             // 初始化为无效文件描述符
    int exportLogReport = 0; // 是否要导出测试报告
    char exportPath[MAX_PATH] = {0};
    total_average_written_speed = 0;  // 写入平均速度总计
    total_average_verified_speed = 0; // 校验平均速度总计

    // 初始化日志文件
    char logPath[MAX_PATH]; // 当前日志
    if (getcwd(logPath, sizeof(logPath)) == NULL)
    {
        strcpy(logPath, "./");
    }
    else
    {
        size_t len = strlen(logPath);
        if (logPath[len - 1] != '/')
        {
            strcat(logPath, "/");
        }
    }
    strcat(logPath, "loglist.log");
    if ((logFile = fopen(logPath, "a")) == NULL)
    {
        logFile = nullptr;
    }

    if (logFile)
    {
        write_log("===== 程序启动 =====");
    }

    // 显示标题
    show_title();

    set_console_color(COLOR_YELLOW);
    char path[1024];
    if (getcwd(path, sizeof(path)) == NULL)
    {
        strcpy(path, "drwtest");
    }

    printf("正确使用格式:\n");
    printf("%s [设备路径] [V] [S] [C] [D] [P]\n\n", path);
    printf(" \"设备路径\" 表示目标设备路径(如/dev/sdb)\n");
    printf("     \"[V]\" 表示是否实时验证(默认为Y)[Y/N]\n");
    printf("     \"[S]\" 表示执行轮次数量（数字）\n");
    printf("     \"[C]\" 表示出错时继续(默认为Y)[Y/N]\n");
    printf("     \"[D]\" 表示是否删除文件(默认为N)[Y/N]\n");
    printf("     \"[P]\" 表示是否导出测试报告(默认为Y)[Y/N]\n\n");
    printf("***********************************\n\n");

    printf("说明:\n");
    printf("* 设备类型: 块设备类型\n");
    printf("* 连接模式: 显示设备的连接模式(SATA, NVMe等)\n");
    printf("* 产品型号: 显示设备的产品型号\n");
    printf("* 程序说明: 采用单线程内存缓冲技术，适用于非root操作\n\n");
    set_console_color(COLOR_RESET);
    set_console_color(COLOR_RED);
    printf("注意事项与免责声明:\n");
    printf("1.数据破坏性:此程序会擦除目标磁盘上的部分数据！请在运行前备份目标设备上的所有重要数据。\n");
    printf("2.设备风险:长时间、高强度的读写测试可能会对质量较差的存储设备造成不可逆的损害，加速其老化或直接导致损坏。请知悉此风险。\n");
    printf("3.正确选择设备:运行时请极度小心，确保选择的是正确的、需要测试的可移动设备，切勿误选系统硬盘。\n");
    printf("4.免责声明:本工具按\"原样\"提供，作者和开发者不对因使用此软件而导致的任何数据丢失、设备损坏或任何其他直接或间接损失承担任何责任。使用者需自行承担所有风险。\n\n");
    set_console_color(COLOR_RESET);

    // 获取驱动器列表
    std::vector<DriveInfo> drives = list_drives();
    int driveCount = drives.size();

    if (driveCount == 0)
    {
        set_console_color(COLOR_RED);
        printf("未找到可用的存储设备\n");
        set_console_color(COLOR_RESET);
        return 1;
    }

    // 显示驱动器列表
    set_console_color(COLOR_CYAN);
    std::cout << "可用驱动器列表:\n";
    std::cout << "序号     设备类型       设备         挂载点         文件系统   总容量    可用空间\n";
    std::cout << "-------------------------------------------------------------------------------\n";
    set_console_color(COLOR_RESET);

    for (size_t i = 0; i < drives.size(); i++)
    {
        std::cout << " " << (i + 1) << "      " << std::setw(12) << std::left << drives[i].type
                  << "  " << std::setw(12) << std::left << drives[i].device
                  << "  " << std::setw(12) << std::left << drives[i].mount_point
                  << "  " << std::setw(8) << std::left << drives[i].filesystem
                  << "  " << std::setw(6) << std::right << std::fixed << std::setprecision(1)
                  << (drives[i].total_size / (1024.0 * 1024.0 * 1024.0)) << "G"
                  << "  " << std::setw(6) << std::right << std::fixed << std::setprecision(1)
                  << (drives[i].free_space / (1024.0 * 1024.0 * 1024.0)) << "G" << std::endl;
    }

    char devicePath[256] = {0};
    int existingFiles = 0;
    double nominalCapacity = 0;   // 标称容量
    double actualCapacity = 0;    // 实际容量
    std::string busType = "未知"; // 总线模式

    // 命令行参数处理
    if (argc >= 2)
    {
        // 第一个参数为序号
        if (isdigit(argv[1][0]))
        {
            int index = atoi(argv[1]) - 1;
            if (index >= 0 && index < driveCount)
            {
                strncpy(devicePath, drives[index].device.c_str(), sizeof(devicePath) - 1);
                busType = drives[index].bus_type;
            }
        }
        // 参数为设备路径
        else
        {
            strncpy(devicePath, argv[1], sizeof(devicePath) - 1);
            // 查找设备信息
            for (const auto &drive : drives)
            {
                if (drive.device == devicePath)
                {
                    busType = drive.bus_type;
                    break;
                }
            }
        }

        if (argc >= 3)
        {
            // 是否启用即时验证
            char yn = toupper(argv[2][0]);
            immediateVerify = (yn == 'Y' || yn == 'N') ? (yn == 'Y') : 1;
        }

        if (argc >= 4)
        {
            // 输入测试轮次(默认1)
            testRounds = atoi(argv[3]);
            if (testRounds < 1)
                testRounds = 1;
        }

        if (argc >= 5)
        {
            // 出错时是否继续
            char yn = toupper(argv[4][0]);
            continueOnError = (yn == 'Y' || yn == 'N') ? (yn == 'Y') : 1;
        }

        // 第五个参数：测试后删除文件
        if (argc >= 6)
        {
            char yn = toupper(argv[5][0]);
            deleteFilesAfterTest = (yn == 'Y' || yn == 'N') ? (yn == 'Y') : 0;
        }

        // 第六个参数：是否要导出测试报告
        if (argc >= 7)
        {
            char yn = toupper(argv[6][0]);
            exportLogReport = (yn == 'Y' || yn == 'N') ? (yn == 'Y') : 1;
        }
    }

    // 未提供设备路径时提示用户选择
    while (devicePath[0] == '\0' && !g_bExit)
    {
        set_console_color(COLOR_WHITE);

        printf("\n 请选择设备序号: ");
        char input[10];

        if (fgets(input, sizeof(input), stdin) == NULL)
        {
            if (feof(stdin))
            {
                // 处理EOF（如Ctrl+D）
                clearerr(stdin);
                continue;
            }
            continue;
        }

        // 去除换行符
        input[strcspn(input, "\n")] = '\0';

        if (isdigit(input[0]))
        {
            int index = atoi(input) - 1;
            if (index >= 0 && index < driveCount)
            {
                strncpy(devicePath, drives[index].device.c_str(), sizeof(devicePath) - 1);
                busType = drives[index].bus_type;

                if (logFile)
                {
                    write_log("用户选择: %s", devicePath);
                }
            }
            else
            {
                set_console_color(COLOR_RED);
                printf("无效选择\n");
                set_console_color(COLOR_RESET);
            }
        }
        else
        {
            set_console_color(COLOR_RED);
            printf("无效输入\n");
            set_console_color(COLOR_RESET);
        }
    }

    if (g_bExit)
    {
        // 清理资源
        if (lpBuffer)
            free(lpBuffer);
        if (Block)
            free(Block);
        if (logFile)
        {
            write_log("用户提前退出");
            fclose(logFile);
        }
        return 0;
    }

    lastActivityTime = GetTickCount64(); // 重置计时器

    // 查找选中的驱动器信息
    DriveInfo selectedDriveInfo;
    for (const auto &drive : drives)
    {
        if (drive.device == devicePath)
        {
            selectedDriveInfo = drive;
            break;
        }
    }

    // 显示驱动器详细信息
    show_drive_details(selectedDriveInfo);

    // 获取容量信息
    nominalCapacity = actualCapacity = selectedDriveInfo.total_size / (1024.0 * 1024.0 * 1024.0);

    // 获取磁盘扇区大小
    int sector_size_fd = open(devicePath, O_RDONLY);
    if (sector_size_fd != -1)
    {
        if (ioctl(sector_size_fd, BLKSSZGET, &bytesPerSector) != 0)
        {
            bytesPerSector = 512; // 默认值
        }
        close(sector_size_fd);
    }

    // 未提供即时验证选项时提示用户
    if (argc < 3)
    {
        char input = get_user_input("是否启用即时验证?[Y/N](默认 Y): ");
        immediateVerify = (input == 'Y');

        if (input != 'Y' && input != 'N' && input != 'y' && input != 'n')
        {
            immediateVerify = 1;
        }

        if (logFile)
        {
            write_log("即时验证: %s", immediateVerify ? "启用" : "禁用");
        }
    }

    // 未提供测试轮次时提示用户
    if (argc < 4)
    {
        printf("输入测试轮次(默认1): ");
        char input[10];
        fgets(input, sizeof(input), stdin);
        testRounds = atoi(input);
        if (testRounds < 1)
            testRounds = 1;

        if (logFile)
        {
            write_log("测试轮次: %d", testRounds);
        }
    }

    // 未提供错误处理选项时提示用户
    if (argc < 5 && testRounds > 1)
    {
        char input = get_user_input("出错时是否继续?[Y/N](默认 Y): ");
        continueOnError = (input == 'Y');

        if (input != 'Y' && input != 'N' && input != 'y' && input != 'n')
        {
            continueOnError = 1;
        }

        if (logFile)
        {
            write_log("出错继续: %s", continueOnError ? "是" : "否");
        }
    }

    // 未提供删除文件选项时提示用户
    if (argc < 6)
    {
        char input = get_user_input("测试完成后是否删除文件?[Y/N](默认 N): ");
        deleteFilesAfterTest = (input == 'Y');

        if (input != 'Y' && input != 'N' && input != 'y' && input != 'n')
        {
            deleteFilesAfterTest = 0;
        }

        if (logFile)
        {
            write_log("删除文件: %s", deleteFilesAfterTest ? "是" : "否");
        }
    }

    // 第六个参数：是否要导出测试报告
    if (argc < 7)
    {
        char input = get_user_input("是否导出测试报告?[Y/N](默认 Y): ");
        exportLogReport = (input == 'Y');

        if (input != 'Y' && input != 'N' && input != 'y' && input != 'n')
        {
            exportLogReport = 1;
        }

        if (exportLogReport)
        {
            printf("请输入导出目录(留空使用当前目录): ");
            fgets(exportPath, MAX_PATH, stdin);

            // 去除换行符
            size_t len = strlen(exportPath);
            if (len > 0 && exportPath[len - 1] == '\n')
            {
                exportPath[len - 1] = '\0';
            }

            // 如果留空则使用当前目录
            if (strlen(exportPath) == 0)
            {
                if (getcwd(exportPath, MAX_PATH) == NULL)
                {
                    strcpy(exportPath, "./");
                }
            }
        }

        if (logFile)
        {
            write_log("是否导出测试报告: %s", exportLogReport ? "是" : "否");
        }
    }

    lastActivityTime = GetTickCount64(); // 重置计时器

    // 是否生成临时日志文件
    char templogPath[MAX_PATH]; // 临时日志
    if (getcwd(templogPath, MAX_PATH) == NULL)
    {
        strcpy(templogPath, "./");
    }
    else
    {
        size_t len = strlen(templogPath);
        if (templogPath[len - 1] != '/')
        {
            strcat(templogPath, "/");
        }
    }
    strcat(templogPath, "temploglist.log");
    // std::lock_guard<std::mutex> lock(logMutex);
    if (exportLogReport)
    {
        remove(templogPath); // 删除临时日志文件
        TemplogFile = fopen(templogPath, "a");
        if (!TemplogFile)
        {
            printf("无法创建临时日志文件: %s\n", templogPath);
        }
    }

    double test_start_time = get_current_time(); // 记录测试开始时间

    // 调整缓冲区大小
    adjust_buffer_size();

    // 确保缓冲区大小是扇区对齐的
    bufferSize = (bufferSize + bytesPerSector - 1) / bytesPerSector * bytesPerSector;
    largeBufferSize = (largeBufferSize + bytesPerSector - 1) / bytesPerSector * bytesPerSector;

    // 分配内存（使用对齐分配）
    auto lpBuffer = std::unique_ptr<uint8_t, decltype(&aligned_free)>(static_cast<uint8_t *>(aligned_malloc(bufferSize, bytesPerSector)), &aligned_free);
    auto Block = std::unique_ptr<uint8_t, decltype(&aligned_free)>(static_cast<uint8_t *>(aligned_malloc(bufferSize, bytesPerSector)), &aligned_free);

    if (!lpBuffer || !Block)
    {
        set_console_color(COLOR_RED);
        printf("内存分配失败\n");
        set_console_color(COLOR_RESET);

        if (logFile)
        {
            write_log("内存分配失败");
            fclose(logFile);
        }
        return 1;
    }

    // 获取挂载点信息
    std::string mountPoint = selectedDriveInfo.mount_point;

    actualCapacity = selectedDriveInfo.free_space / (1024.0 * 1024.0 * 1024.0);

    if (logFile)
    {
        write_log("测试设备: %s", devicePath);
        write_log("标称容量: %.2f GB", nominalCapacity);
        write_log("实际容量: %.2f GB", actualCapacity);
        write_log("总线模式: %s", busType.c_str());
        write_log("挂载点: %s", mountPoint.c_str());
    }

    set_console_color(COLOR_YELLOW);
    printf("\n *** 开始第 1 / %d 轮测试 ***\n\n", testRounds);
    set_console_color(COLOR_RESET);

    if (logFile)
    {
        write_log("开始测试: 1/%d", testRounds);
    }

    // 进度表头
    set_console_color(COLOR_CYAN);
    printf("                                      当前状态\n");
    printf("----------------------------------------------------------------------------------------------------\n");
    set_console_color(COLOR_RESET);

    // 解决goto跳过初始化的问题
    int writeError = 0;
    int fileIndex = 1;
    double totalWritten = 0;
    double startTime = 0;
    double lastUpdateTime = 0;
    double writeStartTime = 0;

    double currentSpeed = 0;         // 当前速度
    double avgSpeed = 0;             // 平均速度
    double remainingMB = 0;          // 计算剩余空间/剩余验证量
    double remainingTime = 0;        // 计算剩余时间
    double progress = 0;             // 计算进度
    const char *color = COLOR_GREEN; // 根据结果选择颜色,默认绿色
    double blockElapsed = 0;         // 块位置
    totalWrittenInRound = 0;         // 总写入量初始化
    // int slowBlockWarning = 0;      // 慢块警告标志

    for (int round = 1; round <= testRounds && !g_bExit; round++)
    {
        // 重置每轮警告计数器
        slowWriteCount = 0;
        slowVerifyCount = 0;
        totalBlocks = 0;
        // slowBlockWarning = 0;
        color = COLOR_GREEN;
        currentRound = round;

        if (round > 1)
        {
            set_console_color(COLOR_YELLOW);
            printf("\n *** 开始第 %d / %d 轮测试 ***\n\n", round, testRounds);
            set_console_color(COLOR_RESET);

            if (logFile)
            {
                write_log("开始测试: %d/%d", round, testRounds);
            }

            set_console_color(COLOR_CYAN);
            printf("                                      当前状态\n");
            printf("----------------------------------------------------------------------------------------------------\n");
            set_console_color(COLOR_RESET);
        }

        // 使用现有文件直接进入验证阶段
        existingFiles = check_existing_files(devicePath);
        if (existingFiles)
        {
            // 现在安全跳转
            goto VERIFY_PHASE;
        }

        lastActivityTime = GetTickCount64(); // 重置计时器

        // 写入阶段 - 重新初始化变量
        writeError = 0;
        fileIndex = 1;
        totalWritten = 0;
        startTime = get_current_time();
        lastUpdateTime = get_current_time();
        writeStartTime = get_current_time(); // 记录写入开始时间

        while (!g_bExit)
        {
            // 初始化文件名字符数组
            std::ostringstream filename_oss;
            filename_oss << mountPoint.c_str() << "/DRW" << std::setfill('0') << std::setw(5) << fileIndex << ".BIN";
            std::string filename = filename_oss.str();
            int bufferSizeForThisFile = bufferSize; // 默认使用全局bufferSize（可能是16MB）
            int writeSuccess = 0;
            double fileWritten = 0;
            uint64_t freeBytesNow = 0;
            try
            {
                FileHandler file(filename, FileHandler::WRITE);

                // 获取当前可用空间
                struct statvfs vfs;
                if (statvfs(mountPoint.c_str(), &vfs) != 0)
                {
                    set_console_color(COLOR_RED);
                    printf("获取可用空间失败\n");
                    set_console_color(COLOR_RESET);
                    writeError = 1;
                    break;
                }

                freeBytesNow = vfs.f_bfree * vfs.f_bsize;

                // 动态调整缓冲区大小
                // 1. 决定本文件使用的缓冲区大小
                int freeSpaceMB = freeBytesNow / (1024 * 1024);
                int currentBufferSize = bufferSize; // 保存当前缓冲区大小

                if (freeSpaceMB < 1)
                {
                    printf("可用空间不足1M，无法完成测试!\n");
                    writeError = 1;
                    break;
                }

                // 如果剩余空间小于2048MB，使用1MB缓冲区
                if (freeSpaceMB < targetFileSize)
                {
                    bufferSizeForThisFile = 1 * 1024 * 1024;
                    if (logFile && currentBufferSize != bufferSizeForThisFile)
                    {
                        write_log("剩余空间不足%dMB，切换为1MB缓冲区", targetFileSize);
                    }
                }
                else
                {
                    if (avgSpeed >= 400.0)
                    {
                        // 写入速度超过400MB/S，缓冲区为128M
                        bufferSizeForThisFile = 128 * 1024 * 1024;
                    }
                    else if (avgSpeed >= 200.0)
                    {
                        // 写入速度超过200MB/S，缓冲区为64M
                        bufferSizeForThisFile = 64 * 1024 * 1024;
                    }
                    else if (avgSpeed >= 100.0)
                    {
                        // 写入速度超过100MB/S，缓冲区为32M
                        bufferSizeForThisFile = 32 * 1024 * 1024;
                    }
                    else if (avgSpeed >= 60.0)
                    {
                        // 写入速度超过60MB/S，缓冲区为16M
                        bufferSizeForThisFile = 16 * 1024 * 1024;
                    }
                    else if (avgSpeed >= 30.0)
                    {
                        // 写入速度超过30MB/S，缓冲区为8M
                        bufferSizeForThisFile = 8 * 1024 * 1024;
                    }
                    else if (avgSpeed >= 15.0)
                    {
                        // 写入速度超过15MB/S，缓冲区为4M
                        bufferSizeForThisFile = 4 * 1024 * 1024;
                    }
                    else if (avgSpeed >= 6.0)
                    {
                        // 写入速度超过6MB/S，缓冲区为2M
                        bufferSizeForThisFile = 2 * 1024 * 1024;
                    }
                    else if (avgSpeed >= 1.0)
                    {
                        // 写入速度超过1MB/S，缓冲区为1M
                        bufferSizeForThisFile = 1 * 1024 * 1024;
                    }
                    else
                    {
                        // 否则使用16MB缓冲区
                        bufferSizeForThisFile = largeBufferSize;
                    }
                }

                // 确保缓冲区大小是扇区对齐的
                bufferSizeForThisFile = (bufferSizeForThisFile + bytesPerSector - 1) / bytesPerSector * bytesPerSector;

                if (currentBufferSize != bufferSizeForThisFile)
                {
                    // 重新分配主缓冲区
                    if (lpBuffer)
                    {
                        lpBuffer = std::unique_ptr<uint8_t, decltype(&aligned_free)>(static_cast<uint8_t *>(aligned_malloc(bufferSizeForThisFile, bytesPerSector)), &aligned_free);
                        if (!lpBuffer)
                        {
                            set_console_color(COLOR_RED);
                            printf("内存分配失败 (lpBuffer)\n");
                            set_console_color(COLOR_RESET);
                            writeError = 1;
                            break;
                        }
                    }

                    // 重新分配验证缓冲区
                    if (Block)
                    {
                        Block = std::unique_ptr<uint8_t, decltype(&aligned_free)>(static_cast<uint8_t *>(aligned_malloc(bufferSizeForThisFile, bytesPerSector)), &aligned_free);
                        if (!Block)
                        {
                            set_console_color(COLOR_RED);
                            printf("内存分配失败 (Block)\n");
                            set_console_color(COLOR_RESET);
                            writeError = 1;
                            break;
                        }
                    }
                }

                // 计算最大可写入块数（使用DWORDLONG防止整数溢出）
                DWORDLONG maxBlocks = freeBytesNow / bufferSizeForThisFile; // 注意这里用 bufferSizeForThisFile
                if (maxBlocks <= 0)
                {
                    set_console_color(COLOR_YELLOW);
                    printf("可用空间不足，无法创建文件\n");
                    set_console_color(COLOR_RESET);
                    break;
                }

                // 确保不超出INT_MAX（安全限制）
                if (maxBlocks > INT_MAX)
                {
                    maxBlocks = INT_MAX;
                }

                // 计算可写入块数（不超过2048MB）
                DWORDLONG maxBlocksPerFile = (DWORDLONG)targetFileSize * 1024 * 1024 / bufferSizeForThisFile; // 这里也是
                DWORDLONG blocksToWrite = std::min(maxBlocks, maxBlocksPerFile);

                if (!is_mount_point_valid(mountPoint.c_str()))
                {
                    set_console_color(COLOR_RED);
                    printf("错误: 挂载点 %s 已失效，设备可能已卸载\n", mountPoint.c_str());
                    set_console_color(COLOR_RESET);
                    writeError = 1;
                    break;
                }
                // 添加调试日志
                if (logFile)
                {
                    write_log("创建文件: %s, 缓冲区大小: %d MB, 块数: %lld", filename.c_str(), bufferSizeForThisFile / (1024 * 1024), blocksToWrite);
                }

                init_xorshift(); // 初始化xorshift算法

                // 写入数据块
                writeSuccess = 1;
                fileWritten = 0;

                for (DWORDLONG block = 0; block < blocksToWrite && !g_bExit; block++)
                {
                    totalBlocks++; // 增加总块数计数

                    // 生成连续随机数据
                    generate_block(lpBuffer.get(), bufferSizeForThisFile);

                    lastActivityTime = GetTickCount64(); // 重置计时器

                    ssize_t bytesWritten;
                    double blockStartTime = get_current_time(); // 写入数据开始计时
                    // 在写入循环中添加
                    for (int retry = 0; retry < RETRY_COUNT; retry++)
                    {
                        // 使用 FileHandler 的 write 方法
                        bytesWritten = file.write(lpBuffer.get(), bufferSizeForThisFile);
                        if (bytesWritten == bufferSizeForThisFile)
                        {
                            break; // 成功写入
                        }

                        if (bytesWritten == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
                        {
                            unsigned int retryDelay = 1000 * (1 << retry); // 指数退避
                            write_log("设备繁忙，等待 %u ms 重试 %d/%d", retryDelay, retry + 1, RETRY_COUNT);
                            usleep(retryDelay * 1000);
                            continue;
                        }

                        if (bytesWritten == -1 || bytesWritten != bufferSizeForThisFile)
                        {
                            // 检查设备状态
                            if (!IsDriveAvailable(devicePath, 1000))
                            {
                                DWORD retryDelay = 1000 * (1 << retry);
                                write_log("设备不可用，等待 %d ms 重试 %d/%d", retryDelay, retry + 1, RETRY_COUNT);
                                usleep(retryDelay * 1000);
                                continue; // 重试
                            }

                            lastActivityTime = GetTickCount64(); // 重置计时器

                            // 其他错误处理
                            set_console_color(COLOR_RED);
                            printf("写入失败: %s (块 %d)(错误: %d)\n", filename.c_str(), (int)block, errno);
                            set_console_color(COLOR_RESET);
                            writeSuccess = 0;
                            break;
                        }

                        if (retry == RETRY_COUNT - 1)
                        {
                            write_log("写入失败，达到最大重试次数");
                            writeSuccess = 0;
                        }
                    }

                    // 确保正确计算写入量（以MB为单位）
                    double now = get_current_time();
                    double elapsed = now - startTime;
                    uint64_t freeBytesNow;
                    blockElapsed = now - blockStartTime; // 写入数据结束

                    double blockSizeMB = (double)bufferSizeForThisFile / (1024.0 * 1024.0);
                    fileWritten += blockSizeMB;
                    totalWritten += blockSizeMB;
                    totalWrittenInRound += blockSizeMB;

                    // 检测慢写入
                    if (blockElapsed > SLOW_WRITE_THRESHOLD)
                    {
                        slowWriteCount++;
                        // slowBlockWarning = 1;

                        if (logFile)
                        {
                            write_log("慢写入: %s 块 %d (%.2f秒)",
                                      filename.c_str(), block, blockElapsed);
                        }
                    }

                    // 确保进度更新逻辑正确
                    if (now - lastUpdateTime > PROGRESS_UPDATE_INTERVAL || block == blocksToWrite - 1)
                    {
                        currentSpeed = blockSizeMB / blockElapsed;
                        if (currentSpeed > peak_written_speed)
                        {
                            peak_written_speed = currentSpeed;
                        }
                        avgSpeed = (elapsed > 0) ? totalWritten / elapsed : 0;

                        struct statvfs vfs_now;
                        if (statvfs(mountPoint.c_str(), &vfs_now) == 0)
                        {
                            freeBytesNow = vfs_now.f_bfree * vfs_now.f_bsize;
                            remainingMB = (double)freeBytesNow / (1024.0 * 1024.0);
                            remainingTime = (avgSpeed > 0.1) ? remainingMB / avgSpeed : -1.0;
                            progress = static_cast<double>(block + 1) / blocksToWrite;

                            if (blockElapsed > SLOW_WRITE_THRESHOLD)
                            {
                                color = COLOR_YELLOW;
                            }
                            else if (blockElapsed > 0.5)
                            {
                                color = COLOR_YELLOW;
                            }

                            show_detailed_progress_bar(
                                progress,
                                color,
                                "写入",
                                get_basename(filename.c_str()),
                                bufferSizeForThisFile / (1024 * 1024),
                                currentSpeed,
                                avgSpeed,
                                remainingMB,
                                remainingTime,
                                (blockElapsed > SLOW_WRITE_THRESHOLD));

                            lastUpdateTime = now;
                        }
                    }
                }
            }
            catch (const std::exception &e)
            {
                std::cerr << "文件写入错误:" << e.what() << '\n';
                write_log("文件写入错误: %s", e.what());
            }
            progress = 1.0;
            // 写入完成后，进度条改为100%
            show_detailed_progress_bar(
                progress,
                color,
                "写入",
                get_basename(filename.c_str()),
                bufferSizeForThisFile / (1024 * 1024),
                currentSpeed,
                avgSpeed,
                remainingMB,
                remainingTime,
                (blockElapsed > SLOW_WRITE_THRESHOLD));

            // 确保文件描述符被关闭
            if (fd != -1)
            {
                close(fd);
                fd = -1;
            }

            if (!writeSuccess)
            {
                writeError = 1;
                break;
            }

            // 获取剩余空间
            struct statvfs vfs_now;
            statvfs(mountPoint.c_str(), &vfs_now);
            freeBytesNow = vfs_now.f_bfree * vfs_now.f_bsize;
            double remainingMB = (double)freeBytesNow / (1024.0 * 1024.0);

            if (peak_written_speed < currentSpeed)
            {
                // 峰值写入速度
                peak_written_speed = currentSpeed;
            }

            // 显示文件写入信息
            set_console_color(COLOR_GREEN);
            printf("\n成功写入: %.0f MB, 剩余空间: %.0f MB\n", fileWritten, remainingMB);
            write_log("成功写入:文件：%s, %.0f MB, 剩余空间: %.0f MB，当前速度 %.2f MB/s，平均速度 %.2f MB/s", filename.c_str(), fileWritten, remainingMB, currentSpeed, avgSpeed);
            set_console_color(COLOR_RESET);

            fileIndex++;

            if (remainingMB < 1)
            {
                break;
            }
        }

        total_average_written_speed += avgSpeed; // 平均写入速度（总计）

        // 确保文件描述符被关闭
        if (fd != -1)
        {
            close(fd);
            fd = -1;
        }

        if (writeError && !continueOnError && !g_bExit)
        {
            set_console_color(COLOR_RED);
            printf("\n写入阶段出错，测试终止\n");
            set_console_color(COLOR_RESET);

            if (logFile)
            {
                write_log("写入阶段出错，测试终止");
            }
            break;
        }

        // 记录写入阶段信息
        if (logFile && !g_bExit)
        {
            double writeTime = get_current_time() - writeStartTime;
            double avgWriteSpeed = writeTime > 0 ? totalWritten / writeTime : 0;
            write_log("%d轮写入: %.2f MB, 平均速度: %.2f MB/s, 慢写入块: %d (%.2f%%)",
                      round, totalWritten, avgWriteSpeed, slowWriteCount,
                      totalBlocks > 0 ? (double)slowWriteCount / totalBlocks * 100 : 0);
        }

        existingFiles = 1; // 标记已有文件

        if (g_bExit)
            break; // 增加退出检查

        // 验证阶段
    VERIFY_PHASE:

        // 初始化验证阶段需要的变量
        int verifySuccess = 1;
        double totalVerified = 0;
        int fileCount = 0;
        double verifyStart = 0;
        int roundErrors = 0;
        double verifyStartTime = 0;
        double lastUpdateTime = 0;

        // 确保缓冲区大小是扇区对齐的
        bufferSize = 1 * 1024 * 1024;
        bufferSize = (bufferSize + bytesPerSector - 1) / bytesPerSector * bytesPerSector;

        // 重新分配验证缓冲区
        if (lpBuffer)
        {
            lpBuffer = std::unique_ptr<uint8_t, decltype(&aligned_free)>(static_cast<uint8_t *>(aligned_malloc(bufferSize, bytesPerSector)), &aligned_free);
            if (!lpBuffer)
            {
                set_console_color(COLOR_RED);
                printf("验证缓冲区分配失败\n");
                set_console_color(COLOR_RESET);
                continue;
            }
        }

        if (immediateVerify && !g_bExit)
        {
            totalVerified = 0;
            fileCount = 1;
            verifyStart = get_current_time();
            roundErrors = 0;
            verifyStartTime = get_current_time(); // 记录验证开始时间
            lastUpdateTime = get_current_time();

            // 计算文件数量和计算总验证大小
            double totalVerifyMB = 0.0;
            while (!g_bExit)
            {
                std::ostringstream filename_oss;
                filename_oss << mountPoint.c_str() << "/DRW" << std::setfill('0') << std::setw(5) << fileCount << ".BIN";
                std::string filename = filename_oss.str();

                // 检查文件是否存在
                struct stat file_stat;
                if (stat(filename.c_str(), &file_stat) != 0)
                {
                    break;
                }

                // 获取文件大小
                FileHandler file(filename, FileHandler::READ);
                uint64_t file_size = file.size();
                totalVerifyMB += (double)file_size / (1024.0 * 1024.0);
                totalVerifiedInRound += (double)file_size / (1024.0 * 1024.0);
                fileCount++;
            }

            for (int i = 1; i < fileCount && !g_bExit; i++)
            {
                try
                {
                    std::ostringstream filename_oss;
                    filename_oss << mountPoint.c_str() << "/DRW" << std::setfill('0') << std::setw(5) << i << ".BIN";
                    std::string filename = filename_oss.str();

                    // 检查文件是否存在
                    struct stat file_stat;
                    if (stat(filename.c_str(), &file_stat) != 0)
                    {
                        break; // 文件不存在，停止验证
                    }

                    FileHandler file(filename, FileHandler::READ);
                    uint64_t file_size = file.size();
                    double fileMB = (double)file_size / (1024.0 * 1024.0);
                    double fileVerified = 0;
                    DWORDLONG blocksInFile = (file_size + bufferSize - 1) / bufferSize;

                    int blockSuccess = 1;
                    BOOL hasError = FALSE;

                    init_xorshift(); // 初始化xorshift算法

                    // 校验数据块
                    for (DWORDLONG block = 0; block < blocksInFile && !g_bExit; block++)
                    {
                        double blockStartTime = get_current_time();
                        totalBlocks++; // 增加总块数计数

                        lastActivityTime = GetTickCount64(); // 重置计时器

                        ssize_t bytesRead;
                        // 在验证循环中添加
                        for (int retry = 0; retry < RETRY_COUNT; retry++)
                        {
                            bytesRead = file.read(lpBuffer.get(), bufferSize);

                            if (bytesRead == bufferSize)
                            {
                                break; // 成功读取
                            }

                            if (bytesRead == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
                            {
                                unsigned int retryDelay = 1000 * (1 << retry); // 指数退避
                                write_log("设备繁忙，等待 %u ms 重试 %d/%d", retryDelay, retry + 1, RETRY_COUNT);
                                usleep(retryDelay * 1000);
                                continue;
                            }

                            if (bytesRead == -1 || bytesRead != bufferSize)
                            {
                                // 检查设备状态
                                if (!IsDriveAvailable(devicePath, 1000))
                                {
                                    write_log("设备不可用，重试 %d/%d", retry + 1, RETRY_COUNT);
                                    usleep(1000000); // 等待1秒
                                    continue;        // 重试
                                }

                                lastActivityTime = GetTickCount64(); // 重置计时器

                                // 其他错误处理
                                set_console_color(COLOR_RED);
                                write_log("读取失败: %s (块号 %llu)(错误: %d)", filename.c_str(), block, errno);
                                blockSuccess = 0;
                                set_console_color(COLOR_RESET);
                                blockSuccess = 0;
                                hasError = TRUE;
                                if (!continueOnError)
                                    break;
                                break;
                            }

                            if (retry == RETRY_COUNT - 1)
                            {
                                write_log("读取失败，达到最大重试次数");
                                blockSuccess = 0;
                            }
                        }

                        if (!verify_block(lpBuffer.get(), bufferSize))
                        {
                            set_console_color(COLOR_RED);
                            printf("验证失败: %s (块号 %llu)\n", filename.c_str(), block);
                            set_console_color(COLOR_RESET);
                            blockSuccess = 0;
                            hasError = TRUE;
                            roundErrors++;
                            totalErrors++;
                            if (!continueOnError)
                                break;
                        }

                        fileVerified += (double)bytesRead / (1024.0 * 1024.0);
                        totalVerified += (double)bytesRead / (1024.0 * 1024.0);

                        // 计算速度和剩余时间
                        double now = get_current_time();
                        double elapsed = now - verifyStart;
                        double blockElapsed = now - blockStartTime;

                        // 检测慢校验
                        if (blockElapsed > SLOW_VERIFY_THRESHOLD)
                        {
                            slowVerifyCount++;
                            // slowBlockWarning = 1;

                            if (logFile)
                            {
                                write_log("慢校验: %s 块 %llu (%.2f秒)", filename.c_str(), block, blockElapsed);
                            }
                        }

                        // 更新进度每0.1秒或最后一个块
                        if (now - lastUpdateTime > PROGRESS_UPDATE_INTERVAL || block == blocksInFile - 1)
                        {
                            currentSpeed = (bytesRead / (1024.0 * 1024.0)) / blockElapsed;
                            if (currentSpeed > peak_written_speed)
                            {
                                peak_written_speed = currentSpeed;
                            }
                            avgSpeed = (elapsed > 0) ? totalVerified / elapsed : 0;

                            // 计算剩余验证量
                            remainingMB = totalVerifyMB - totalVerified;

                            // 计算剩余时间
                            remainingTime = (avgSpeed > 0.1) ? remainingMB / avgSpeed : -1.0;

                            // 计算进度
                            progress = static_cast<double>(block + 1) / blocksInFile;

                            // 根据结果选择颜色
                            color = blockSuccess ? COLOR_GREEN : COLOR_RED;
                            if (blockElapsed > SLOW_VERIFY_THRESHOLD)
                            {
                                color = COLOR_YELLOW;
                            }
                            else if (blockElapsed > 0.5)
                            {
                                color = COLOR_YELLOW;
                            }

                            // 显示进度
                            show_detailed_progress_bar(
                                progress,
                                color,
                                "验证",
                                get_basename(filename.c_str()),
                                bufferSize / (1024 * 1024),
                                currentSpeed,
                                avgSpeed,
                                remainingMB,
                                remainingTime,
                                hasError);

                            lastUpdateTime = now;
                        }
                    }

                    // 文件验证完成，显示100%进度
                    remainingMB = totalVerifyMB - totalVerified;
                    progress = 1.0;
                    show_detailed_progress_bar(
                        progress,
                        color,
                        "验证",
                        get_basename(filename.c_str()),
                        bufferSize / (1024 * 1024),
                        currentSpeed,
                        avgSpeed,
                        remainingMB,
                        remainingTime,
                        hasError);

                    // 确保文件描述符被关闭
                    if (fd != -1)
                    {
                        close(fd);
                        fd = -1;
                    }

                    if (peak_verified_speed < currentSpeed)
                    {
                        // 峰值校验速度
                        peak_verified_speed = currentSpeed;
                    }

                    if (blockSuccess && !g_bExit)
                    {
                        set_console_color(COLOR_GREEN);
                        printf("\n成功验证: %.0f MB\n", fileMB);
                        write_log("成功验证:文件：%s, %.0f MB, 剩余空间: %.0f MB，当前速度 %.2f MB/s，平均速度 %.2f MB/s", filename.c_str(), fileMB, remainingMB, currentSpeed, avgSpeed);
                        set_console_color(COLOR_RESET);
                    }
                    else if (!blockSuccess && !g_bExit)
                    {
                        verifySuccess = 0;
                        set_console_color(COLOR_RED);
                        printf("\n验证失败: %.0f MB\n", fileMB);
                        write_log("验证失败:文件：%s, %.0f MB, 剩余空间: %.0f MB，当前速度 %.2f MB/s，平均速度 %.2f MB/s", filename.c_str(), fileMB, remainingMB, currentSpeed, avgSpeed);
                        set_console_color(COLOR_RESET);

                        if (!continueOnError)
                            break;
                    }
                }
                catch (const std::exception &e)
                {
                    std::cerr << "文件读取错误:" << e.what() << '\n';
                    write_log("文件读取错误: %s", e.what());
                }
            }

            total_average_verified_speed += avgSpeed; // 平均验证速度总计

            if (verifySuccess && !g_bExit)
            {
                set_console_color(COLOR_GREEN);
                printf("\n文件验证全部通过\n");
                set_console_color(COLOR_RESET);
                passedRounds++;

                if (logFile)
                {
                    write_log("%d轮验证通过", round);
                }
            }
            else if (!g_bExit)
            {
                set_console_color(COLOR_RED);
                printf("\n验证未通过，检测到 %d MB 数据错误\n", roundErrors);
                set_console_color(COLOR_RESET);

                if (logFile)
                {
                    write_log("%d轮验证失败: %d MB数据错误", round, roundErrors);
                }
            }

            // 记录验证阶段信息
            if (logFile && !g_bExit)
            {
                double verifyTime = get_current_time() - verifyStartTime;
                double avgVerifySpeed = verifyTime > 0 ? totalVerifyMB / verifyTime : 0;
                write_log("%d轮验证: %.2f MB, 平均速度: %.2f MB/s, 慢验证块: %d (%.2f%%)",
                          round, totalVerifyMB, avgVerifySpeed, slowVerifyCount,
                          totalBlocks > 0 ? (double)slowVerifyCount / totalBlocks * 100 : 0);
            }
        }

        // 在每轮测试结束后检查慢操作比例
        if (!g_bExit && totalBlocks > 0)
        {
            double slowRatio = static_cast<double>(slowWriteCount + slowVerifyCount) / totalBlocks;

            if (slowRatio > 0.6)
            {
                set_console_color(COLOR_YELLOW);
                printf("\n 警告:超过60%%的块操作延迟过高!");
                printf("该设备不稳定，请慎重使用!\n");
                set_console_color(COLOR_RESET);

                if (logFile)
                {
                    write_log("警告: 超过60%的块操作延迟过高，设备可能不稳定!");
                }
            }
        }

        // 准备下一轮测试，删除文件
        if (round < testRounds && !g_bExit)
        {
            set_console_color(COLOR_YELLOW);
            printf("\n准备下一轮测试，删除文件...\n");

            if (logFile)
            {
                write_log("准备下一轮测试，删除文件");
            }

            delete_test_files(mountPoint);

            existingFiles = 0;
        }

        if (g_bExit)
            break; // 增加退出检查
    } // 结束for循环（轮次）

    double test_end_time = get_current_time();         // 记录测试结束时间
    total_test_time = test_end_time - test_start_time; // 计算总时长

    // 测试后删除文件
    if (deleteFilesAfterTest && !g_bExit)
    {
        delete_test_files(mountPoint);
    }

    // 获取最终总线模式信息
    std::string finalBusType = get_disk_bus_type(devicePath);
    if (logFile)
    {
        write_log("总线模式: %s", finalBusType.c_str());
    }

    // 生成测试结果
    char result[256];
    if (!g_bExit)
    {
        show_test_result(testRounds, passedRounds, totalErrors, get_device_type_name(devicePath));
        if (passedRounds == testRounds && totalErrors == 0)
        {
            strcpy(result, "全部通过验证无错误");
        }
        else if (totalErrors > 0)
        {
            snprintf(result, sizeof(result), "检测到 %d MB 数据错误", totalErrors);
        }
        else
        {
            snprintf(result, sizeof(result), "%d/%d 轮通过验证", passedRounds, testRounds);
        }
    }
    else
    {
        set_console_color(COLOR_YELLOW);
        printf("\n\n用户中断 %d 轮测试\n", currentRound);

        if (totalErrors > 0)
        {
            set_console_color(COLOR_RED);
            printf("检测到 %d MB 数据错误，该设备不可靠!\n", totalErrors);
        }
        else if (passedRounds > 0)
        {
            set_console_color(COLOR_GREEN);
            printf("已完成验证未检测到错误!\n");
        }
        else
        {
            set_console_color(COLOR_YELLOW);
            printf("未完成任何测试轮次，无法确定设备状态\n");
        }
        set_console_color(COLOR_RESET);

        // 生成中断报告
        if (currentRound > 0)
        {
            if (passedRounds == currentRound && totalErrors == 0)
            {
                strcpy(result, "测试被中断，已完成部分无错误");
            }
            else if (totalErrors > 0)
            {
                snprintf(result, sizeof(result), "测试被中断，检测到 %d MB 数据错误", totalErrors);
            }
            else
            {
                snprintf(result, sizeof(result), "测试被中断，%d/%d 轮通过验证", passedRounds, currentRound);
            }
        }
    }

    // 在测试结束后添加导出提示
    if (exportLogReport)
    {
        printf("正在生成测试报告.... \n");
        // 生成报告（包含总线模式信息）
        std::string reportfilename = generate_report(devicePath, testRounds, currentRound, passedRounds, totalErrors,
                                                     nominalCapacity, actualCapacity, result, finalBusType.c_str(),
                                                     exportLogReport ? exportPath : NULL);

        char reportPath[MAX_PATH];
        if (reportfilename != " ")
        {
            snprintf(reportPath, sizeof(reportPath), "%s/%s", exportPath, reportfilename.c_str());
        }
        else
        {
            snprintf(reportPath, sizeof(reportPath), "%s/test_report_*.txt", exportPath);
        }

        set_console_color(COLOR_CYAN);
        printf("\n测试报告已导出到: %s\n", exportPath);
        printf("测试报告: %s\n", reportPath);
        set_console_color(COLOR_RESET);
		

        // 删除临时日志文件
        if (TemplogFile)
        {
            fclose(TemplogFile);
			char templogPath[MAX_PATH];
			if (getcwd(templogPath, MAX_PATH) == NULL) {
				strcpy(templogPath, "./");
			} else {
				size_t len = strlen(templogPath);
				if (templogPath[len - 1] != '/') {
					strcat(templogPath, "/");
				}
			}
			strcat(templogPath, "temploglist.log");
			
			if (remove(templogPath) == 0) {
				write_log("已删除临时日志文件: %s", templogPath);
			} else {
				write_log("删除临时日志文件失败: %s", strerror(errno));
			}
            TemplogFile = nullptr;
        }
    }

    // 关闭日志文件
    if (!g_bExit)
    {
        if (logFile)
        {
            write_log("===== 测试结束 =====");
            fclose(logFile);
            logFile = nullptr;
        }
    }
    else
    {
        if (logFile)
        {
            write_log("===== 测试被中断 =====");
            fclose(logFile);
            logFile = nullptr;
        }
    }
	
	// 在程序退出前添加清理
    if (lockFileFd != -1) {
        flock(lockFileFd, LOCK_UN);
        close(lockFileFd);
        remove("drwtestlock.lck");
    }
    

    // 在程序结束时释放内存
    if (lpBuffer)
    {
        lpBuffer = nullptr;
    }
    if (Block)
    {
        Block = nullptr;
    }
    // 关闭文件描述符
    if (fd != -1)
    {
        close(fd);
        fd = -1;
    }

    set_console_color(COLOR_WHITE);
    printf("\n测试完成，按任意键退出...");
    getchar(); // 等待用户按键

    return 0;
}